pygame加pyopengl加多进程试验

学习pyopengl的时候,经常要不停的调试参数,以便理解和掌握绘图函数、变换函数的特点。但是一个程序一个程序的调整,很影响学习效率,于是想到用多线程或者多进程试验同时加载两个窗口,同时解决多个学习内容。

下面是试验的代码:

# pygame加PyOpenGL多进程编程,可以打开多个窗口,同时调用多个绘图函数,有利于学习测试时提高效率
# 可以在不同的窗口初始化函数、绘图函数中测试不同的参数和不同的图形绘制
# 调整、修改后一并运行
from multiprocessing import Process
import pygame as pg
from pygame.locals import *
import sys
from OpenGL.GL import *
from OpenGL.GLU import * 
import numpy as np
import math
#————————————————————————————————————————————————————
# 谢尔平斯基三角锥部分
pTt=np.zeros(12).reshape(4,3)
dd=(60/180)*math.pi
ddsin=math.sin(dd)
def base_Tetra(l=1):
    pTt[1]=1,0,0
    pTt[2]=0.5*l,0,l*ddsin
    pTt[3]=0.5*l,l*math.sqrt(2/3),l*(1/(2*math.sqrt(3)))

#绘制最基础的三角锥
def draw_Tetra(a,b,c,d):
    glBegin(GL_LINE_LOOP)
    glVertex3fv(a)
    glVertex3fv(b)
    glVertex3fv(c)
    glEnd()

    glBegin(GL_LINE_LOOP)
    glVertex3fv(a)
    glVertex3fv(b)
    glVertex3fv(d)
    glEnd()

    glBegin(GL_LINE_LOOP)
    glVertex3fv(b)
    glVertex3fv(c)
    glVertex3fv(d)
    glEnd()
    
    glBegin(GL_LINE_LOOP)
    glVertex3fv(c)
    glVertex3fv(a)
    glVertex3fv(d)
    glEnd()

#递归计算谢尔平斯基三角锥
def drawSherpin(a,b,c,d,n):
    # 非常好理解的n次递归过程,比嵌套循环n次还要浅显易懂
    if n<=1:
        n=1
        draw_Tetra(a*50,b*50,c*50,d*50)
    else:
        ab=(a+b)/2
        bc=(b+c)/2
        ac=(a+c)/2
        ad=(a+d)/2
        bd=(b+d)/2
        cd=(c+d)/2
        n=n-1
        drawSherpin(a,ab,ac,ad,n)
        drawSherpin(ab,b,bc,bd,n)
        drawSherpin(ac,bc,c,cd,n)
        drawSherpin(ad,bd,cd,d,n)
#————————————————————————————————————————————————————————
#圆锥部分
def drawscene():
    #颜色标记
    iPivot=1
    #***可以调整下面的参数看看图形绘制的差别*******
    #清除看不见的面(如显卡支持OpenGL会通过显卡实现,否则其通过软件实现)
    #如果学习图形学可能需要自己用软件实现,挺艰辛的嘿嘿
    #glEnable(GL_CULL_FACE)
    #深度测试
    glEnable(GL_DEPTH_TEST)
    #图形背面设定,如果前面不设置CULL,默认画出背面,这里设为用线条画出背面
    glPolygonMode(GL_BACK,GL_LINE)
    # 保证窗口变化大小时,场景的角度变换不会受影响而错乱。
    # 用glPushMatrix()会重置场景矩阵,则需要变量以实现动画
    glMatrixMode(GL_MODELVIEW) 
    #glPushMatrix()
    #-------
    #旋转
    glRotatef(1,1.,0.,0.)
    glRotatef(1,0.,1.,0.)
    glRotatef(1,0.,0.,1.)
    #-------
    #*******
    
    #圆锥面,16个面
    glBegin(GL_TRIANGLE_FAN)
    glVertex3f(0.,0.,50.)
    ang=0
    for i in range(17):
        x=25*np.cos(ang)
        y=25*np.sin(ang)
        if iPivot % 2 == 0:
            glColor3f(0.,1.,0.)
        else:
            glColor3f(1.,0.,0.)
        glVertex3f(x,y,0)
        ang+=np.pi/8
        iPivot+=1
    glEnd()
    
    #圆锥底面
    glBegin(GL_TRIANGLE_FAN)
    glVertex3f(0.,0.,0.)
    #逆时针从2*np.pi开始-
    #ang=2*np.pi 
    #顺时针从0角度开始+
    ang=0
    for i in range(17):
        x=25*np.cos(ang)
        y=25*np.sin(ang)
        if iPivot % 2 == 0:
            glColor3f(0.,1.,0.)
        else:
            glColor3f(1.,0.,0.)
        glVertex3f(x,y,0)
        #逆时针递减
        #ang-=np.pi/8
        #顺时针递增
        ang+=np.pi/8

        iPivot+=1
    glEnd()
    #由于没有使用变量进行动画绘制因此不需要下面语句
    #glPopMatrix()
    #glFlush()
#——————————————————————————————————————
# 窗口初始化与窗口缩放所需的部分
def setupRC():
    #可以调整下面参数试试不同的效果
    #顺时针正面否则默认逆时针正面
    #GL_CW顺时针正面,GL_CCW逆时针正面(缺省是CCW)
    #glFrontFace(GL_CW)
    #着色方式是平涂,缺省是渐变色或者说柔化GL_SMOOTH
    glShadeModel(GL_FLAT)
    #初始化背景颜色为黑
    glClearColor(0.,0.,0.,1.)
    glTranslatef(0,0,-155)
    # glRotatef(-45,1.,0.,0.)

def initScense(width,height):
    
    pg.init()
    display=(width,height)
    aspectratio=display[0]/display[1]
    pg.display.set_mode(display,DOUBLEBUF|OPENGL|RESIZABLE)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(45,(display[0]/display[1]),10,500)
    setupRC()
    
def changeSize(w,h):
    # 在pygame环境里似乎不用超心h=0的危险,但是为了考虑图形正常绘制,可以考虑限制w和h的极小值
    # 具体语句可自行添加
    display=(w,h)
    aspectratio=display[0]/display[1]
    pg.display.set_mode(display,DOUBLEBUF|OPENGL|RESIZABLE)
    glMatrixMode(GL_PROJECTION) #该行语句保证窗口大小变化后比例维持初始状态
    glLoadIdentity()
    gluPerspective(45,(display[0]/display[1]),10,500)
    setupRC()
    
#————————————————————————————————————————————————————
# 事件处理部分,可以自行添加鼠标、键盘、游戏手柄和飞行模拟操纵杆事件
def handleEvent():
    for event in pg.event.get():
        if event.type==pg.QUIT:
            pg.quit()
            quit()
        elif event.type==pg.VIDEORESIZE:
            changeSize(event.w,event.h)
#——————————————————————————————————
# 绘图主循环部分
def mainloop(window_title):
    while True:
        handleEvent()
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        # 根据窗口编号选择不同的绘图函数
        # 也可以考虑放在循环外提高效率,但是代码要重复写
        # 如果不同的进程需要不同的OpenG初始化参数,这个选择可以放在更上一层
        if window_title=='Window 1':
            drawscene()
        else:
            #试试不加这个语句,然后缩放窗口什么后果
            glMatrixMode(GL_MODELVIEW)
            #旋转
            glRotatef(1,1.,0.,0.)
            glRotatef(1,0.,1.,0.)
            glRotatef(1,0.,0.,1.)
            drawSherpin(pTt[0],pTt[1],pTt[2],pTt[3],5)

        pg.display.flip()
        pg.time.wait(20)

#————————————————————————————————
# 进程部分,可以一个进程一个函数,不同进程的窗口初始化可以不一样,自己琢磨,这里我偷懒了
def window_process(window_title, width, height):
    initScense(width,height)
    mainloop(window_title)

# 初始化谢尔平斯基三角锥数组
base_Tetra()
# 创建两个窗口的进程
process1 = Process(target=window_process, args=("Window 1", 400, 300))
process2 = Process(target=window_process, args=("Window 2", 600, 400))
 
# 启动进程
process1.start()
process2.start()
 
# 等待进程结束(可选)
process1.join()
process2.join()

程序很简单,用两个进程分别打开OpenGL窗口,一个绘制谢尔平斯基三角锥,一个绘制圆锥,并且实现了窗口缩放同时保持比例和变换的持续性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值