pyopengl之cube

博客主要讲述几个坐标系变化矩阵的确定,未采用网上常见的现场矩阵库,而是用numpy自定义矩阵。还给出几种坐标体系的直观图示链接。此外,提到使用python库调用opengl接口时涉及数据类型转换,并给出示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

    最 主要的是几个坐标系的变化矩阵的确定。网上很多资料的都是采用现场的矩阵库。此处使用numpy自定义矩阵。

    几种坐标体系的直观图示及功能如下图,转自:https://learnopengl.com/Getting-started/Coordinate-Systems

 

   此外使用python库,在调用opengl接口时,涉及到数据类型转换。例如

    float_size = sizeof(c_float)
    vertex_offset    = c_void_p(0 * float_size)  

   等 

# coding: utf-8
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import sys
from ctypes import sizeof, c_float, c_void_p, c_uint, string_at

from shader import *
import numpy, math

vertices=[
    -0.5, -0.5, -0.5,  0.0, 0.0,0.3,
     0.5, -0.5, -0.5,  1.0, 0.0,0.4,
     0.5,  0.5, -0.5,  1.0, 1.0,0.5,
     0.5,  0.5, -0.5,  1.0, 1.0,0.6,
    -0.5,  0.5, -0.5,  0.0, 1.0,0.7,
    -0.5, -0.5, -0.5,  0.0, 0.0,0.8,

    -0.5, -0.5,  0.5,  0.0, 0.0,0.2,
     0.5, -0.5,  0.5,  1.0, 0.0,0.4,
     0.5,  0.5,  0.5,  1.0, 1.0,0.3,
     0.5,  0.5,  0.5,  1.0, 1.0,0.6,
    -0.5,  0.5,  0.5,  0.0, 1.0,0.8,
    -0.5, -0.5,  0.5,  0.0, 0.0,1.0,

    -0.5,  0.5,  0.5,  1.0, 0.0,1.0,
    -0.5,  0.5, -0.5,  1.0, 1.0,0.3,
    -0.5, -0.5, -0.5,  0.0, 1.0,0.4,
    -0.5, -0.5, -0.5,  0.0, 1.0,0.7,
    -0.5, -0.5,  0.5,  0.0, 0.0,0.7,
    -0.5,  0.5,  0.5,  1.0, 0.0,0.7,

     0.5,  0.5,  0.5,  1.0, 0.0,0.8,
     0.5,  0.5, -0.5,  1.0, 1.0,0.8,
     0.5, -0.5, -0.5,  0.0, 1.0,0.8,
     0.5, -0.5, -0.5,  0.0, 1.0,0.8,
     0.5, -0.5,  0.5,  0.0, 0.0,0.8,
     0.5,  0.5,  0.5,  1.0, 0.0,0.8,

    -0.5, -0.5, -0.5,  0.0, 1.0,0.9,
     0.5, -0.5, -0.5,  1.0, 1.0,0.9,
     0.5, -0.5,  0.5,  1.0, 0.0,0.9,
     0.5, -0.5,  0.5,  1.0, 0.0,0.9,
    -0.5, -0.5,  0.5,  0.0, 0.0,0.9,
    -0.5, -0.5, -0.5,  0.0, 1.0,0.9,

    -0.5,  0.5, -0.5,  0.0, 1.0,0.5,
     0.5,  0.5, -0.5,  1.0, 1.0,0.5,
     0.5,  0.5,  0.5,  1.0, 0.0,0.5,
     0.5,  0.5,  0.5,  1.0, 0.0,0.5,
    -0.5,  0.5,  0.5,  0.0, 0.0,0.5,
    -0.5,  0.5, -0.5,  0.0, 1.0,0.5
]

screenWidth=512
screenHeight=512

cameraAngleX=218
cameraAngleY=10

zdistance=-0.2
mouseLeftDown=False
mouseRightDown=False
mouseX=0.0
mouseY=0.0

cameraDistance=1.7


def mydraw():

    # clear
    global cameraAngleX
    global cameraAngleY  
    global  zdistance
    #cameraAngleX=-55+cameraAngleX
    # zdistance=zdistance+0.1
    # if (zdistance>0.9):
        # zdistance=-0.9
    
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
    
    sinx=math.sin(math.radians(cameraAngleX))
    cosx=math.cos(math.radians(cameraAngleX))
    
    siny=math.sin(math.radians(cameraAngleY))
    cosy=math.cos(math.radians(cameraAngleY))
    #model 变换,将各个顶点分别以Y轴和X轴进行旋转。将顶点左边由物体自身的坐标体系转变为世界坐标体系
    modely = numpy.array([ cosy, 0.0, -siny,0.0, 
                           0,    1.0, 0.0,0.0, 
                           siny, 0, cosy, 0.0, 
                           0.0, 0.0, 0.0, 1.0], numpy.float32)
    modelx = numpy.array([ 1.0 ,0.0, -0.0,0.0,  
                          0.0,cosx, -sinx, 0,  
                          0.0, sinx, cosx, 0.0, 
                          0.0, 0.0, 0.0, 1.0], numpy.float32)
                                
    project=  numpy.array([ 1.0, 0.0,0.0, 0.0, 
                                0.0, 1, 0, 0.0, 
                                0.0, 0, -1/4, 0.0, 
                                0.0, 0.0, 0.0, 1.0], numpy.float32)
    #view 坐标转换,即物体离摄像机的远近。                            
    view=  numpy.array([ 1.0, 0.0,0.0, 0.0, 
                         0.0, 1, 0, 0.0, 
                         0.0, 0, 1, zdistance, 
                         0.0, 0.0, 0.0, 1.0], numpy.float32)
                                
    project=project.reshape(4,4)
    modelx=modelx.reshape(4,4)
    modely=modely.reshape(4,4)
    model=numpy.dot(modelx,modely)
    view=view.reshape(4,4)
       
    buffers = glGenBuffers(1)
    float_size = sizeof(c_float)
    vertex_offset    = c_void_p(0 * float_size)    
    glBindBuffer(GL_ARRAY_BUFFER, buffers)
    glBufferData(GL_ARRAY_BUFFER, 
            len(vertices)*4,  # byte size
            (ctypes.c_float*len(vertices))(*vertices), 
            GL_STATIC_DRAW)
    
    
    
    
    glVertexAttribPointer(0,3,GL_FLOAT, False, 6 * float_size, vertex_offset)
    glEnableVertexAttribArray(0) 
    
    color_offset    = c_void_p(3 * float_size) 
    glVertexAttribPointer(1,3,GL_FLOAT, False, 6 * float_size, color_offset)
    glEnableVertexAttribArray(1) 
    
    global shader
    if shader==None:
            shader=Shader()
            shader.initShader('''
   
    layout (location = 0) in vec3 aPos; 
    layout (location = 1) in vec3 acolor;
    out vec3 Color; 
    uniform  mat4 matrix; 
    uniform  mat4 view;
    uniform  mat4 project ;
    
    void main()
    {
        gl_Position = project*view*matrix*vec4(aPos.x, aPos.y, aPos.z, 1); 
        Color=acolor;
        
       
    }
            ''',
            '''
    out vec3 FragColor; 
    in vec3 Color;
    void main()
    {
        
        FragColor =Color; 
    }
            ''')

    
    shader.begin()
    mvp_matrix_loc = glGetUniformLocation(shader.program, 'matrix' )
    glUniformMatrix4fv(mvp_matrix_loc,1,GL_FALSE, model) 
    vp_matrix_loc = glGetUniformLocation(shader.program, 'view' )
    glUniformMatrix4fv(vp_matrix_loc,1,GL_FALSE, view)

    p_matrix_loc = glGetUniformLocation(shader.program, 'project' )
    glUniformMatrix4fv(p_matrix_loc,1,GL_FALSE, project)   
    
    
    glDrawArrays(GL_TRIANGLES, 0,36)
   
    shader.end()
    glDisableVertexAttribArray(0)
    glDisableVertexAttribArray(1)
    
   
    
def disp_func():    
    mydraw()    
    glutSwapBuffers()
    
def timerCB(millisec):

    glutTimerFunc(millisec, timerCB, millisec)
    glutPostRedisplay()
# 鼠标事件的响应处理。获取光标的位置信息,并更新到model 变化矩阵中,借此更新顶点的世界坐标  
def mouseCB( button,  state,  x,  y):
    global mouseX 
    global mouseY 
    mouseX = x
    mouseY = y
    global mouseLeftDown
    if(button == GLUT_LEFT_BUTTON):
    
        if(state == GLUT_DOWN):
        
            mouseLeftDown = True
            
        
        elif(state == GLUT_UP):
            mouseLeftDown = False
       

    elif(button == GLUT_RIGHT_BUTTON):
    
        if(state == GLUT_DOWN):
        
            mouseRightDown = True
        
        elif(state == GLUT_UP):
            mouseRightDown = False
    
    


def mouseMotionCB( x,  y):
    global cameraAngleX
    global cameraAngleY     
    global mouseLeftDown 
    
    global mouseX 
    global mouseY 
    
    if(mouseLeftDown):
    
        cameraAngleY += (x - mouseX)
        cameraAngleX += (y - mouseY)
        mouseX = x
        mouseY = y
        print(cameraAngleX)
    
    if(mouseRightDown):
    
        cameraDistance -= (y - mouseY) * 0.2
        mouseY = y
        
if __name__=="__main__":
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH| GLUT_STENCIL)
    glutInitWindowSize(screenWidth, screenHeight)
    glutCreateWindow(b"vbo")
    
    glutDisplayFunc(disp_func)
    glutTimerFunc(330, timerCB, 330)    
    glutMouseFunc(mouseCB) 
    glutMotionFunc(mouseMotionCB)
    
    glEnable(GL_DEPTH_TEST)
   
    
    glutMainLoop()

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

proware

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值