- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我移植了spinningcube的.cpp版本在那里找到了 python,以便更好地理解 opengl 并创建新的东西。虽然我得到了与第 6 版和第 7 版书籍源代码的编译版本相同的结果,因为两个版本的程序相同,但该程序在当前状态下仅显示绿屏。 OpenGl Superbible 第 7 版的书。第 177 页显示了一个旋转的彩色立方体应该四处飞行。任何帮助将不胜感激。
更新 - 2019 年 6 月 24 日 - 我更新了代码,以便立方体按照 Rabbid76 的优秀代码出现、旋转和移动。谢谢。
#!/usr/bin/python3
import sys
import time
import math
fullscreen = True
# sys.path.append("../shared")
# from math3d import m3dDegToRad, m3dRotationMatrix44, M3DMatrix44f, m3dLoadIdentity44, \
# m3dTranslateMatrix44, m3dScaleMatrix44, \
# m3dMatrixMultiply44, m3dTransposeMatrix44, \
# m3dRadToDeg
import numpy.matlib
import numpy as np
try:
from OpenGL.GLUT import *
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, \
glBindVertexArray
except:
print ('''
ERROR: PyOpenGL not installed properly.
''')
sys.exit()
from math import cos, sin
from array import array
M3D_PI = 3.14159265358979323846
M3D_PI_DIV_180 = M3D_PI / 180.0
M3D_INV_PI_DIV_180 = 57.2957795130823229
# Translate matrix. Only 4x4 matrices supported
def m3dTranslateMatrix44(m, x, y, z):
m[12] += x
m[13] += y
m[14] += z
def m3dDegToRad(num):
return (num * M3D_PI_DIV_180)
def m3dRadToDeg(num):
return (num * M3D_INV_PI_DIV_180)
def m3dOrtho(l, r, t, b, n, f):
return (GLfloat * 16)(
2/(r-l), 0, 0, 0,
0, 2/(t-b), 0, 0,
0, 0, -2/(f-n), 0,
-(r+l)/(r-l), -(t+b)/(t-b), -(f+n)/(f-n), 1)
def m3dPerspective(fov_y, aspect, n, f):
a = aspect
ta = math.tan( fov_y / 2 )
return (GLfloat * 16)(
1/(ta*a), 0, 0, 0,
0, 1/ta, 0, 0,
0, 0, -(f+n)/(f-n), -1,
0, 0, -2*f*n/(f-n), 0)
# Creates a 4x4 rotation matrix, takes radians NOT degrees
def m3dRotationMatrix44(m, angle, x, y, z):
s = sin(angle)
c = cos(angle)
mag = float((x * x + y * y + z * z) ** 0.5)
if mag == 0.0:
m3dLoadIdentity(m)
return
x /= mag
y /= mag
z /= mag
xx = x * x
yy = y * y
zz = z * z
xy = x * y
yz = y * z
zx = z * x
xs = x * s
ys = y * s
zs = z * s
one_c = 1.0 - c
m[0] = (one_c * xx) + c
m[1] = (one_c * xy) - zs
m[2] = (one_c * zx) + ys
m[3] = 0.0
m[4] = (one_c * xy) + zs
m[5] = (one_c * yy) + c
m[6] = (one_c * yz) - xs
m[7] = 0.0
m[8] = (one_c * zx) - ys
m[9] = (one_c * yz) + xs
m[10] = (one_c * zz) + c
m[11] = 0.0
m[12] = 0.0
m[13] = 0.0
m[14] = 0.0
m[15] = 1.0
def m3dMultiply(A, B):
C = (GLfloat * 16)(*identityMatrix)
for k in range(0, 4):
for j in range(0, 4):
C[k*4+j] = A[0*4+j] * B[k*4+0] + A[1*4+j] * B[k*4+1] + \
A[2*4+j] * B[k*4+2] + A[3*4+j] * B[k*4+3]
return C
def translate(tx, ty, tz):
"""creates the matrix equivalent of glTranslate"""
return np.array([1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
tx, ty, tz, 1.0], np.float32)
def rotation_matrix(axis, theta):
"""
Return the rotation matrix associated with counterclockwise rotation about
the given axis by theta radians.
"""
axis = np.asarray(axis)
axis = axis / math.sqrt(np.dot(axis, axis))
a = math.cos(theta / 2.0)
b, c, d = -axis * math.sin(theta / 2.0)
aa, bb, cc, dd = a * a, b * b, c * c, d * d
bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d
return np.array([[aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac), 0],
[2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab), 0],
[2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc, 0],
[0,0,0,1]])
identityMatrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]
mv_location = (GLfloat * 16)(*identityMatrix)
proj_location = (GLfloat * 16)(*identityMatrix)
proj_matrix = (GLfloat * 16)(*identityMatrix)
many_cubes = False
# Vertex program
vs_source = '''
#version 410 core
in vec4 position;
out VS_OUT
{
vec4 color;
} vs_out;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
void main(void)
{
gl_Position = proj_matrix * mv_matrix * position;
vs_out.color = position * 2.0 + vec4(0.5, 0.5, 0.5, 0.0);
}
'''
# Fragment program
fs_source = '''
#version 410 core
out vec4 color;
in VS_OUT
{
vec4 color;
} fs_in;
void main(void)
{
color = fs_in.color;
}
'''
def compile_program(vertex_source, fragment_source):
global mv_location
global proj_location
vertex_shader = None
fragment_shader = None
if vertex_source:
vertex_shader = glCreateShader(GL_VERTEX_SHADER)
glShaderSource(vertex_shader, vertex_source)
glCompileShader(vertex_shader)
if not glGetShaderiv(vertex_shader, GL_COMPILE_STATUS):
raise Exception('failed to compile shader "%s":\n%s' %
('vertex_shader', glGetShaderInfoLog(vertex_shader)))
if fragment_source:
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER)
glShaderSource(fragment_shader, fragment_source)
glCompileShader(fragment_shader)
if not glGetShaderiv(fragment_shader, GL_COMPILE_STATUS):
raise Exception('failed to compile shader "%s":\n%s' %
('fragment_shader', glGetShaderInfoLog(fragment_shader)))
program = glCreateProgram()
glAttachShader(program, vertex_shader)
glAttachShader(program, fragment_shader)
glLinkProgram(program)
mv_location = glGetUniformLocation(program, "mv_matrix");
proj_location = glGetUniformLocation(program, "proj_matrix");
vao = GLuint(0)
glGenVertexArrays(1, vao);
glBindVertexArray(vao);
vertex_positions = [
-0.25, 0.25, -0.25,
-0.25, -0.25, -0.25,
0.25, -0.25, -0.25,
0.25, -0.25, -0.25,
0.25, 0.25, -0.25,
-0.25, 0.25, -0.25,
0.25, -0.25, -0.25,
0.25, -0.25, 0.25,
0.25, 0.25, -0.25,
0.25, -0.25, 0.25,
0.25, 0.25, 0.25,
0.25, 0.25, -0.25,
0.25, -0.25, 0.25,
-0.25, -0.25, 0.25,
0.25, 0.25, 0.25,
-0.25, -0.25, 0.25,
-0.25, 0.25, 0.25,
0.25, 0.25, 0.25,
-0.25, -0.25, 0.25,
-0.25, -0.25, -0.25,
-0.25, 0.25, 0.25,
-0.25, -0.25, -0.25,
-0.25, 0.25, -0.25,
-0.25, 0.25, 0.25,
-0.25, -0.25, 0.25,
0.25, -0.25, 0.25,
0.25, -0.25, -0.25,
0.25, -0.25, -0.25,
-0.25, -0.25, -0.25,
-0.25, -0.25, 0.25,
-0.25, 0.25, -0.25,
0.25, 0.25, -0.25,
0.25, 0.25, 0.25,
0.25, 0.25, 0.25,
-0.25, 0.25, 0.25,
-0.25, 0.25, -0.25 ]
buffer = GLuint(0)
glGenBuffers(1, buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
#ar=numpy.array(vertex_positions, dtype='float32')
ar=array("f",vertex_positions)
glBufferData(GL_ARRAY_BUFFER, ar.tostring(), GL_STATIC_DRAW)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None);
glEnableVertexAttribArray(0);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
return program
class Scene:
def __init__(self, width, height):
self.width = width
self.height = height
def display(self):
global mv_location
global proj_location
global proj_matrix
global many_cubes
currentTime = time.time()
green = [ 0.0, 0.25, 0.0, 1.0 ]
one = 1.0;
glViewport(0, 0, int((1360/2)-(512/2)), int((768/2)-(512/2)))
glClearBufferfv(GL_COLOR, 0, green);
glClearBufferfv(GL_DEPTH, 0, one);
glUseProgram(compile_program(vs_source, fs_source))
#proj_matrix = m3dOrtho(-1, 1, -1, 1, -10, 10)
#proj_matrix = m3dPerspective(50.0*math.pi/180.0, 512/512, 0.1, 1000.0)
#proj_matrix = m3dPerspective(m3dDegToRad(50.0), float(self.width) / float(self.height), 0.1, 1000.0);
glUniformMatrix4fv(proj_location, 1, GL_FALSE, proj_matrix)
if (many_cubes == True):
for i in range(0, 24):
f = i + currentTime * 0.3;
mv_matrix = (GLfloat * 16)(*identityMatrix)
T = (GLfloat * 16)(*identityMatrix)
m3dTranslateMatrix44(T, 0, 0, -4)
W = (GLfloat * 16)(*identityMatrix)
m3dTranslateMatrix44(W, sin(2.1 * f) * 0.5, cos(1.7 * f) * 0.5, sin(1.3 * f) * cos(1.5 * f) * 2.0)
RX = (GLfloat * 16)(*identityMatrix)
m3dRotationMatrix44(RX, currentTime * m3dDegToRad(45.0), 0.0, 1.0, 0.0)
RY = (GLfloat * 16)(*identityMatrix)
m3dRotationMatrix44(RY, currentTime * m3dDegToRad(81.0), 1.0, 0.0, 0.0)
mv_matrix = m3dMultiply(W, m3dMultiply(T, m3dMultiply(RY, RX)))
# or can multiply with numpy
#R = np.matmul(np.array(W).reshape(4,4) , np.matmul(np.array(RX).reshape(4,4), np.array(RY).reshape(4,4)))
#mv_matrix = np.matmul(R, np.array(T).reshape(4,4))
# third way this could be done
# T = np.matrix(translate(0.0, 0.0, -4.0)).reshape(4,4)
# W = np.matrix(translate(sin(2.1 * f) * 0.5, cos(1.7 * f) * 0.5, sin(1.3 * f) * cos(1.5 * f) * 2.0)).reshape(4,4)
# RX = np.matrix(rotation_matrix( [1.0, 0.0, 0.0], currentTime * m3dDegToRad(17.0)))
# RY = np.matrix(rotation_matrix( [0.0, 1.0, 0.0], currentTime * m3dDegToRad(13.0)))
# mv_matrix = RX * RY * T * W
glUniformMatrix4fv(mv_location, 1, GL_FALSE, mv_matrix)
glDrawArrays(GL_TRIANGLES, 0, 36)
else:
f = currentTime * 0.3;
mv_matrix = (GLfloat * 16)(*identityMatrix)
T = (GLfloat * 16)(*identityMatrix)
m3dTranslateMatrix44(T, 0, 0, -4)
W = (GLfloat * 16)(*identityMatrix)
m3dTranslateMatrix44(W, sin(2.1 * f) * 0.5, cos(1.7 * f) * 0.5, sin(1.3 * f) * cos(1.5 * f) * 2.0)
RX = (GLfloat * 16)(*identityMatrix)
m3dRotationMatrix44(RX, currentTime * m3dDegToRad(45.0), 0.0, 1.0, 0.0)
RY = (GLfloat * 16)(*identityMatrix)
m3dRotationMatrix44(RY, currentTime * m3dDegToRad(81.0), 1.0, 0.0, 0.0)
mv_matrix = m3dMultiply(W, m3dMultiply(T, m3dMultiply(RY, RX)))
# second way to that can multiply with numpy
#R = np.matmul(np.array(W).reshape(4,4) , np.matmul(np.array(RX).reshape(4,4), np.array(RY).reshape(4,4)))
#mv_matrix = np.matmul(R, np.array(T).reshape(4,4))
# third way this could be done
# T = np.matrix(translate(0.0, 0.0, -4.0)).reshape(4,4)
# W = np.matrix(translate(sin(2.1 * f) * 0.5, cos(1.7 * f) * 0.5, sin(1.3 * f) * cos(1.5 * f) * 2.0)).reshape(4,4)
# RX = np.matrix(rotation_matrix( [1.0, 0.0, 0.0], currentTime * m3dDegToRad(17.0)))
# RY = np.matrix(rotation_matrix( [0.0, 1.0, 0.0], currentTime * m3dDegToRad(13.0)))
# mv_matrix = RX * RY * T * W
glUniformMatrix4fv(mv_location, 1, GL_FALSE, mv_matrix)
glDrawArrays(GL_TRIANGLES, 0, 36)
glutSwapBuffers()
def reshape(self, width, height):
global proj_matrix
proj_matrix = m3dPerspective(m3dDegToRad(50.0), float(self.width) / float(self.height), 0.1, 1000.0);
self.width = width
self.height = height
def keyboard(self, key, x, y ):
global fullscreen
global many_cubes
print ('key:' , key)
if key == b'\x1b': # ESC
sys.exit()
elif key == b'f' or key == b'F': #fullscreen toggle
if (fullscreen == True):
glutReshapeWindow(512, 512)
glutPositionWindow(int((1360/2)-(512/2)), int((768/2)-(512/2)))
fullscreen = False
else:
glutFullScreen()
fullscreen = True
elif key == b'm' or key == b'M':
if (many_cubes == True):
many_cubes = False
else:
many_cubes = True
print('done')
def init(self):
pass
def timer(self, blah):
glutPostRedisplay()
glutTimerFunc( int(1/60), self.timer, 0)
time.sleep(1/60.0)
if __name__ == '__main__':
start = time.time()
glutInit()
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(512, 512)
w1 = glutCreateWindow('OpenGL SuperBible - Spinny Cube')
glutInitWindowPosition(int((1360/2)-(512/2)), int((768/2)-(512/2)))
fullscreen = False
many_cubes = False
#glutFullScreen()
scene = Scene(512,512)
glutReshapeFunc(scene.reshape)
glutDisplayFunc(scene.display)
glutKeyboardFunc(scene.keyboard)
glutIdleFunc(scene.display)
#glutTimerFunc( int(1/60), scene.timer, 0)
scene.init()
glutMainLoop()
最佳答案
矩阵必须由 Identity Matrix 初始化ech 矩阵需要它的“自己的”数据数组:
identityMatrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]
mv_matrix = (GLfloat * 16)(*identityMatrix)
proj_matrix = (GLfloat * 16)(*identityMatrix)
<小时/>
如果投影矩阵是单位矩阵,则几何图形必须位于标准化设备空间中。归一化的设备空间的范围是从(-1,-1,-1)到(1,1,1),形成一个完美的立方体体积。您的几何图形被 View 体积的远平面剪切,因为您已将 z 平移设置为 -4.0。
设置 Orthographic Projection矩阵,“增加” View 量:
r = right, l = left, b = bottom, t = top, n = near, f = far
X: 2/(r-l) 0 0 0
y: 0 2/(t-b) 0 0
z: 0 0 -2/(f-n) 0
t: -(r+l)/(r-l) -(t+b)/(t-b) -(f+n)/(f-n) 1
def m3dOrtho(l, r, t, b, n, f):
return (GLfloat * 16)(
2/(r-l), 0, 0, 0,
0, 2/(t-b), 0, 0,
0, 0, -2/(f-n), 0,
-(r+l)/(r-l), -(t+b)/(t-b), -(f+n)/(f-n), 1)
proj_matrix = m3dOrtho(-1, 1, -1, 1, -10, 10)
glUniformMatrix4fv(proj_location, 1, GL_FALSE, proj_matrix)
mv_matrix = (GLfloat * 16)(*identityMatrix)
m3dTranslateMatrix44(mv_matrix, 0.0, 0.0, -4.0)
m3dTranslateMatrix44(mv_matrix, sin(2.1 * f) * 0.5,
cos(1.7 * f) * 0.5,
sin(1.3 * f) * cos(1.5 * f) * 2.0)
<小时/>
进一步注意,类似 glRotatef
的操作和 gluPerspective
更改已弃用的固定函数管道的当前矩阵,如果您使用具有自己的矩阵制服的着色器,则完全没有任何意义。
注意,矩阵运算也可以由 PyGLM 等库执行。或NumPy .
<小时/>对于 3D 对象,我建议使用 Perspective Projection :
x: 1/(ta*a) 0 0 0
y: 0 1/ta 0 0
z: 0 0 -(f+n)/(f-n) -1
t: 0 0 -2*f*n/(f-n) 0
地点:
a = w / h
ta = tan( fov_y / 2 );
2 * n / (r-l) = 1 / (ta * a)
2 * n / (t-b) = 1 / ta
例如
import math
def m3dPerspective(fov_y, aspect, n, f):
a = aspect
ta = math.tan( fov_y / 2 )
return (GLfloat * 16)(
1/(ta*a), 0, 0, 0,
0, 1/ta, 0, 0,
0, 0, -(f+n)/(f-n), -1,
0, 0, -2*f*n/(f-n), 0)
proj_matrix = m3dPerspective(50.0*math.pi/180.0, 512/512, 0.1, 1000.0)
glUniformMatrix4fv(proj_location, 1, GL_FALSE, proj_matrix)
关于python - 为什么 OpenGL Superbible 第 6、7 版的 spincube 示例的 python 代码中没有出现立方体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56681770/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!