天元浪子VBO的完整代码(勿喷)

这是天元浪子博客的代码:

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import numpy as np

IS_PERSPECTIVE = True                               # 透视投影
VIEW = np.array([-0.8, 0.8, -0.8, 0.8, 1.0, 20.0])  # 视景体的left/right/bottom/top/near/far六个面
SCALE_K = np.array([1.0, 1.0, 1.0])                 # 模型缩放比例
EYE = np.array([0.0, 0.0, 2.0])                     # 眼睛的位置(默认z轴的正方向)
LOOK_AT = np.array([0.0, 0.0, 0.0])                 # 瞄准方向的参考点(默认在坐标原点)
EYE_UP = np.array([0.0, 1.0, 0.0])                  # 定义对观察者而言的上方(默认y轴的正方向)
WIN_W, WIN_H = 640, 480                             # 保存窗口宽度和高度的变量
LEFT_IS_DOWNED = False                              # 鼠标左键被按下
MOUSE_X, MOUSE_Y = 0, 0                             # 考察鼠标位移量时保存的起始位置

def getposture():
    global EYE, LOOK_AT
    
    dist = np.sqrt(np.power((EYE-LOOK_AT), 2).sum())
    if dist > 0:
        phi = np.arcsin((EYE[1]-LOOK_AT[1])/dist)
        theta = np.arcsin((EYE[0]-LOOK_AT[0])/(dist*np.cos(phi)))
    else:
        phi = 0.0
        theta = 0.0
        
    return dist, phi, theta
    
DIST, PHI, THETA = getposture()                     # 眼睛与观察目标之间的距离、仰角、方位角

def init():
    glClearColor(0.0, 0.0, 0.0, 1.0) # 设置画布背景色。注意:这里必须是4个参数
    glEnable(GL_DEPTH_TEST)          # 开启深度测试,实现遮挡关系
    glDepthFunc(GL_LEQUAL)           # 设置深度测试函数(GL_LEQUAL只是选项之一)

def draw():
    global IS_PERSPECTIVE, VIEW
    global EYE, LOOK_AT, EYE_UP
    global SCALE_K
    global WIN_W, WIN_H
        
    # 清除屏幕及深度缓存
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    
    # 设置投影(透视投影)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    
    if WIN_W > WIN_H:
        if IS_PERSPECTIVE:
            glFrustum(VIEW[0]*WIN_W/WIN_H, VIEW[1]*WIN_W/WIN_H, VIEW[2], VIEW[3], VIEW[4], VIEW[5])
        else:
            glOrtho(VIEW[0]*WIN_W/WIN_H, VIEW[1]*WIN_W/WIN_H, VIEW[2], VIEW[3], VIEW[4], VIEW[5])
    else:
        if IS_PERSPECTIVE:
            glFrustum(VIEW[0], VIEW[1], VIEW[2]*WIN_H/WIN_W, VIEW[3]*WIN_H/WIN_W, VIEW[4], VIEW[5])
        else:
            glOrtho(VIEW[0], VIEW[1], VIEW[2]*WIN_H/WIN_W, VIEW[3]*WIN_H/WIN_W, VIEW[4], VIEW[5])
        
    # 设置模型视图
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
        
    # 几何变换
    glScale(SCALE_K[0], SCALE_K[1], SCALE_K[2])
        
    # 设置视点
    gluLookAt(
        EYE[0], EYE[1], EYE[2], 
        LOOK_AT[0], LOOK_AT[1], LOOK_AT[2],
        EYE_UP[0], EYE_UP[1], EYE_UP[2]
    )
    
    # 设置视口
    glViewport(0, 0, WIN_W, WIN_H)
    
    # ---------------------------------------------------------------
    glBegin(GL_LINES)                    # 开始绘制线段(世界坐标系)
    
    # 以红色绘制x轴
    glColor4f(1.0, 0.0, 0.0, 1.0)        # 设置当前颜色为红色不透明
    glVertex3f(-0.8, 0.0, 0.0)           # 设置x轴顶点(x轴负方向)
    glVertex3f(0.8, 0.0, 0.0)            # 设置x轴顶点(x轴正方向)
    
    # 以绿色绘制y轴
    glColor4f(0.0, 1.0, 0.0, 1.0)        # 设置当前颜色为绿色不透明
    glVertex3f(0.0, -0.8, 0.0)           # 设置y轴顶点(y轴负方向)
    glVertex3f(0.0, 0.8, 0.0)            # 设置y轴顶点(y轴正方向)
    
    # 以蓝色绘制z轴
    glColor4f(0.0, 0.0, 1.0, 1.0)        # 设置当前颜色为蓝色不透明
    glVertex3f(0.0, 0.0, -0.8)           # 设置z轴顶点(z轴负方向)
    glVertex3f(0.0, 0.0, 0.8)            # 设置z轴顶点(z轴正方向)
    
    glEnd()                              # 结束绘制线段
    
    # ---------------------------------------------------------------
    glBegin(GL_TRIANGLES)                # 开始绘制三角形(z轴负半区)
    
    glColor4f(1.0, 0.0, 0.0, 1.0)        # 设置当前颜色为红色不透明
    glVertex3f(-0.5, -0.366, -0.5)       # 设置三角形顶点
    glColor4f(0.0, 1.0, 0.0, 1.0)        # 设置当前颜色为绿色不透明
    glVertex3f(0.5, -0.366, -0.5)        # 设置三角形顶点
    glColor4f(0.0, 0.0, 1.0, 1.0)        # 设置当前颜色为蓝色不透明
    glVertex3f(0.0, 0.5, -0.5)           # 设置三角形顶点
    
    glEnd()                              # 结束绘制三角形
    
    # ---------------------------------------------------------------
    glBegin(GL_TRIANGLES)                # 开始绘制三角形(z轴正半区)
    
    glColor4f(1.0, 0.0, 0.0, 1.0)        # 设置当前颜色为红色不透明
    glVertex3f(-0.5, 0.5, 0.5)           # 设置三角形顶点
    glColor4f(0.0, 1.0, 0.0, 1.0)        # 设置当前颜色为绿色不透明
    glVertex3f(0.5, 0.5, 0.5)            # 设置三角形顶点
    glColor4f(0.0, 0.0, 1.0, 1.0)        # 设置当前颜色为蓝色不透明
    glVertex3f(0.0, -0.366, 0.5)         # 设置三角形顶点
    
    glEnd()                              # 结束绘制三角形
    
    # ---------------------------------------------------------------
    glutSwapBuffers()                    # 切换缓冲区,以显示绘制内容
    
def reshape(width, height):
    global WIN_W, WIN_H
    
    WIN_W, WIN_H = width, height
    glutPostRedisplay()
    
def mouseclick(button, state, x, y):
    global SCALE_K
    global LEFT_IS_DOWNED
    global MOUSE_X, MOUSE_Y
    
    MOUSE_X, MOUSE_Y = x, y
    if button == GLUT_LEFT_BUTTON:
        LEFT_IS_DOWNED = state==GLUT_DOWN
    elif button == 3:
        SCALE_K *= 1.05
        glutPostRedisplay()
    elif button == 4:
        SCALE_K *= 0.95
        glutPostRedisplay()
    
def mousemotion(x, y):
    global LEFT_IS_DOWNED
    global EYE, EYE_UP
    global MOUSE_X, MOUSE_Y
    global DIST, PHI, THETA
    global WIN_W, WIN_H
    
    if LEFT_IS_DOWNED:
        dx = MOUSE_X - x
        dy = y - MOUSE_Y
        MOUSE_X, MOUSE_Y = x, y
        
        PHI += 2*np.pi*dy/WIN_H
        PHI %= 2*np.pi
        THETA += 2*np.pi*dx/WIN_W
        THETA %= 2*np.pi
        r = DIST*np.cos(PHI)
        
        EYE[1] = DIST*np.sin(PHI)
        EYE[0] = r*np.sin(THETA)
        EYE[2] = r*np.cos(THETA)
            
        if 0.5*np.pi < PHI < 1.5*np.pi:
            EYE_UP[1] = -1.0
        else:
            EYE_UP[1] = 1.0
        
        glutPostRedisplay()
    
def keydown(key, x, y):
    global DIST, PHI, THETA
    global EYE, LOOK_AT, EYE_UP
    global IS_PERSPECTIVE, VIEW
    
    if key in [b'x', b'X', b'y', b'Y', b'z', b'Z']:
        if key == b'x': # 瞄准参考点 x 减小
            LOOK_AT[0] -= 0.01
        elif key == b'X': # 瞄准参考 x 增大
            LOOK_AT[0] += 0.01
        elif key == b'y': # 瞄准参考点 y 减小
            LOOK_AT[1] -= 0.01
        elif key == b'Y': # 瞄准参考点 y 增大
            LOOK_AT[1] += 0.01
        elif key == b'z': # 瞄准参考点 z 减小
            LOOK_AT[2] -= 0.01
        elif key == b'Z': # 瞄准参考点 z 增大
            LOOK_AT[2] += 0.01
        
        DIST, PHI, THETA = getposture()
        glutPostRedisplay()
    elif key == b'\r': # 回车键,视点前进
        EYE = LOOK_AT + (EYE - LOOK_AT) * 0.9
        DIST, PHI, THETA = getposture()
        glutPostRedisplay()
    elif key == b'\x08': # 退格键,视点后退
        EYE = LOOK_AT + (EYE - LOOK_AT) * 1.1
        DIST, PHI, THETA = getposture()
        glutPostRedisplay()
    elif key == b' ': # 空格键,切换投影模式
        IS_PERSPECTIVE = not IS_PERSPECTIVE 
        glutPostRedisplay()

if __name__ == "__main__":
    glutInit()
    displayMode = GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH
    glutInitDisplayMode(displayMode)

    glutInitWindowSize(WIN_W, WIN_H)
    glutInitWindowPosition(300, 200)
    glutCreateWindow('Quidam Of OpenGL')
    
    init()                              # 初始化画布
    glutDisplayFunc(draw)               # 注册回调函数draw()
    glutReshapeFunc(reshape)            # 注册响应窗口改变的函数reshape()
    glutMouseFunc(mouseclick)           # 注册响应鼠标点击的函数mouseclick()
    glutMotionFunc(mousemotion)         # 注册响应鼠标拖拽的函数mousemotion()
    glutKeyboardFunc(keydown)           # 注册键盘输入的函数keydown()
    
    glutMainLoop()     
————————————————
版权声明:本文为优快云博主「天元浪子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/xufive/article/details/86565130

但天元浪子的VBO有问题

其实只需在那代码做点小修改即可:

#先设置cube函数,在设置绘图draw()函数之前
def cube():       
    vertices = np.array([
        0.3, 0.6, 0.9, -0.5, 0.5, 0.5,   # c0-v0
        0.6, 0.9, 0.3, 0.5, 0.5, 0.5,    # c1-v1
        0.9, 0.3, 0.6, 0.5, -0.5, 0.5,   # c2-v2 
        0.3, 0.9, 0.6, -0.5, -0.5, 0.5,  # c3-v3 
        0.6, 0.3, 0.9, -0.5, 0.5, -0.5,  # c4-v4 
        0.9, 0.6, 0.3, 0.5, 0.5, -0.5,   # c5-v5 
        0.3, 0.9, 0.9, 0.5, -0.5, -0.5,  # c6-v6 
        0.9, 0.9, 0.3, -0.5, -0.5, -0.5  # c7-v7
        ],'f')
    indices = np.array([
        0, 1, 2, 3, # v0-v1-v2-v3 (front)
        4, 5, 1, 0, # v4-v5-v1-v0 (top)
        3, 2, 6, 7, # v3-v2-v6-v7 (bottom)
        5, 4, 7, 6, # v5-v4-v7-v6 (back)
        1, 5, 6, 2, # v1-v5-v6-v2 (right)
        4, 0, 3, 7  # v4-v0-v3-v7 (left)
        ],'H')
    
    vbo_vertices = vbo.VBO(vertices)
    vbo_indices = vbo.VBO(indices,target = GL_ELEMENT_ARRAY_BUFFER)
    eboLength = len(indices)

    vbo_vertices.bind()
    glInterleavedArrays(GL_C3F_V3F,0,None)
    vbo_indices.bind()
    glDrawElements(GL_QUADS,eboLength,GL_UNSIGNED_SHORT,None)
    vbo_indices.unbind()
    vbo_vertices.unbind()

注意!上面那段代码和天元浪子博客中的VBO有点不一样(有几处修改)

接下来,在把天元浪子的代码中的draw函数改成

def Draw():
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    
    if WIN_W > WIN_H:
        if IS_PERSPECTIVE:
            glFrustum(VIEW[0]*WIN_W/WIN_H, VIEW[1]*WIN_W/WIN_H, VIEW[2], VIEW[3], VIEW[4], VIEW[5])
        else:
            glOrtho(VIEW[0]*WIN_W/WIN_H, VIEW[1]*WIN_W/WIN_H, VIEW[2], VIEW[3], VIEW[4], VIEW[5])
    else:
        if IS_PERSPECTIVE:
            glFrustum(VIEW[0], VIEW[1], VIEW[2]*WIN_H/WIN_W, VIEW[3]*WIN_H/WIN_W, VIEW[4], VIEW[5])
        else:
            glOrtho(VIEW[0], VIEW[1], VIEW[2]*WIN_H/WIN_W, VIEW[3]*WIN_H/WIN_W, VIEW[4], VIEW[5])
        
    # 设置模型视图
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
        
    # 几何变换
    glScale(SCALE_K[0], SCALE_K[1], SCALE_K[2])
        
    # 设置视点
    gluLookAt(
        EYE[0], EYE[1], EYE[2], 
        LOOK_AT[0], LOOK_AT[1], LOOK_AT[2],
        EYE_UP[0], EYE_UP[1], EYE_UP[2]
    )
    
    # 设置视口
    glViewport(0, 0, WIN_W, WIN_H)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    cube()                         
    glutSwapBuffers()

运行代码结果应该是这个样子:

 由于本人是小白,讲的十分笼统,抱歉

链接:写给 python 程序员的 OpenGL 教程_天元浪子的博客-优快云博客_pyopengl教程

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值