gpt4 book ai didi

python - 为什么 OpenGL Superbible 第 6、7 版的 spincube 示例的 python 代码中没有出现立方体

转载 作者:行者123 更新时间:2023-12-01 07:41:34 25 4
gpt4 key购买 nike

我移植了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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com