尝试使用opengl函数glMapBufferRange在python中创建alienrain

尝试使用opengl函数glMapBufferRange在python中创建alienrain,python,python-3.x,opengl,glsl,glut,Python,Python 3.x,Opengl,Glsl,Glut,我从OpenGL Superbible移植的alien rain程序只有4行代码导致了问题。使用函数glMapBufferRange 更新:Rabbid76的优秀代码解决了这个问题,并提供了有价值的解释见解。多谢各位 所需文件: alienrain.py的源代码 #!/usr/bin/python3 import sys import time sys.path.append("./shared") #from sbmloader import SBMObject # locatio

我从OpenGL Superbible移植的alien rain程序只有4行代码导致了问题。使用函数glMapBufferRange

更新:Rabbid76的优秀代码解决了这个问题,并提供了有价值的解释见解。多谢各位

所需文件:

alienrain.py的源代码

#!/usr/bin/python3

import sys
import time

sys.path.append("./shared")

#from sbmloader import SBMObject    # location of sbm file format loader
from ktxloader import KTXObject    # location of ktx file format loader

#from sbmath import m3dDegToRad, m3dRadToDeg, m3dTranslateMatrix44, m3dRotationMatrix44, m3dMultiply, m3dOrtho, m3dPerspective, rotation_matrix, translate, m3dScaleMatrix44

fullscreen = True

import numpy.matlib
import numpy as np
import math 

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()

identityMatrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]

render_prog = GLuint(0)
render_vao = GLuint(0)

tex_alien_array = GLuint(0)
rain_buffer = GLuint(0)

droplet_x_offset = []
droplet_rot_speed = []
droplet_fall_speed = []


seed = 0x13371337
import random
import ctypes
random.seed (0x13371337)
def random_float():
    # global seed
    # res=0.0
    # tmp=0

    # seed *= 16807;

    # tmp = seed ^ (seed >> 4) ^ (seed << 15);

    # res = (tmp >> 9) | 0x3F800000;

    # return (res - 1.0);
    return (random.random() - 1.0)

class Scene:

    def __init__(self, width, height):
        global render_prog
        global render_vao
        global tex_alien_array
        global rain_buffer

        global droplet_x_offset, droplet_rot_speed, droplet_fall_speed

        self.width = width
        self.height = height

        vs = GLuint(0)
        fs = GLuint(0)

        vs_source = '''
#version 410 core

layout (location = 0) in int alien_index;

out VS_OUT
{
    flat int alien;
    vec2 tc;
} vs_out;

struct droplet_t
{
    float x_offset;
    float y_offset;
    float orientation;
    float unused;
};

layout (std140) uniform droplets
{
    droplet_t droplet[256];
};

void main(void)
{
    const vec2[4] position = vec2[4](vec2(-0.5, -0.5),
                                     vec2( 0.5, -0.5),
                                     vec2(-0.5,  0.5),
                                     vec2( 0.5,  0.5));
    vs_out.tc = position[gl_VertexID].xy + vec2(0.5);
    float co = cos(droplet[alien_index].orientation);
    float so = sin(droplet[alien_index].orientation);
    mat2 rot = mat2(vec2(co, so),
                    vec2(-so, co));
    vec2 pos = 0.25 * rot * position[gl_VertexID];
    gl_Position = vec4(pos.x + droplet[alien_index].x_offset,
                       pos.y + droplet[alien_index].y_offset,
                       0.5, 1.0);
    vs_out.alien = alien_index % 64;
}

'''

        fs_source = '''
#version 410 core

layout (location = 0) out vec4 color;

in VS_OUT
{
    flat int alien;
    vec2 tc;
} fs_in;

uniform sampler2DArray tex_aliens;

void main(void)
{
    color = texture(tex_aliens, vec3(fs_in.tc, float(fs_in.alien)));
}

'''

        vs = glCreateShader(GL_VERTEX_SHADER)
        glShaderSource(vs, vs_source)
        glCompileShader(vs)

        glGetShaderInfoLog(vs)

        fs = glCreateShader(GL_FRAGMENT_SHADER)
        glShaderSource(fs, fs_source)
        glCompileShader(fs)

        glGetShaderInfoLog(vs)

        render_prog = glCreateProgram()
        glAttachShader(render_prog, vs)
        glAttachShader(render_prog, fs)
        glLinkProgram(render_prog)

        glDeleteShader(vs)
        glDeleteShader(fs)

        glGetProgramInfoLog(render_prog)

        glGenVertexArrays(1, render_vao)
        glBindVertexArray(render_vao)

        ktxobj = KTXObject()

        tex_alien_array = ktxobj.ktx_load("aliens.ktx")

        glBindTexture(GL_TEXTURE_2D_ARRAY, tex_alien_array)
        glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)

        glGenBuffers(1, rain_buffer)
        glBindBuffer(GL_UNIFORM_BUFFER, rain_buffer)


        glBufferData(GL_UNIFORM_BUFFER, 256*4*4, None, GL_DYNAMIC_DRAW)


        for i in range(0, 256):
            droplet_x_offset.append(random_float() * 2.0 - 1.0)
            droplet_rot_speed.append( (random_float() + 0.5) * (-3.0 if (i & 1) else 3.0)  )
            droplet_fall_speed.append ( random_float() + 0.2 )

        glBindVertexArray(render_vao);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    def display(self):
        global rain_buffer

        green = [ 0.0, 0.1, 0.0, 0.0 ]
        currentTime = time.time()
        t = currentTime
        glViewport(0, 0, self.width, self.height)
        glClearBufferfv(GL_COLOR, 0, green)

        glUseProgram(render_prog);

        glBindBufferBase(GL_UNIFORM_BUFFER, 0, rain_buffer);
        droplet = glMapBufferRange(GL_UNIFORM_BUFFER, 0, 256*4*4, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT)
        float_array = ((ctypes.c_float * 4) * 256).from_address(droplet) 



        for i in range(0, 256):
            float_array[i][0] =  droplet_x_offset[i] + 2
            float_array[i][1] =  2.0-math.fmod((t + float(i)) * droplet_fall_speed[i], 4.31 ) * random_float()
            float_array[i][2] =  droplet_rot_speed[i] * t * random_float() * math.pi
            float_array[i][3] = 0.0

        glUnmapBuffer(GL_UNIFORM_BUFFER);

        for alien_index in range(0, 256):
            glVertexAttribI1i(0, alien_index);
            glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);


        glutSwapBuffers()

    def reshape(self, width, height):
        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

        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 - Alien Rain')
    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()
#/usr/bin/python3
导入系统
导入时间
sys.path.append(“./共享”)
#从sbmloader导入SBMObject#sbm文件格式加载程序的位置
从ktxloader导入KTXObject#ktx文件格式加载程序的位置
#从sbmath导入m3dDegToRad、M3dDradToDeg、m3dTranslateMatrix44、m3dRotationMatrix44、m3dMultiply、m3dOrtho、m3dPerspective、旋转矩阵、平移、m3dScaleMatrix44
全屏=真
导入numpy.matlib
将numpy作为np导入
输入数学
尝试:
从OpenGL.GLUT导入*
从OpenGL.GL导入*
从OpenGL.GLU导入*
从OpenGL.raw.GL.ARB.vertex\u数组\u对象导入GLGEnVertexArray、glBindVertexArray
除:
打印(“”)
错误:PyOpenGL未正确安装。
''')
sys.exit()
identityMatrix=[1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1]
render_prog=GLuint(0)
render_vao=GLuint(0)
tex_alien_数组=GLuint(0)
雨水缓冲区=GLuint(0)
液滴x_偏移量=[]
液滴旋转速度=[]
液滴下落速度=[]
种子=0x1337137
随机输入
导入ctypes
random.seed(0x1337137)
def random_float():
#全球种子
#res=0.0
#tmp=0
#种子*=16807;
#tmp=seed^(seed>>4)^(seed>9)| 0x3F800000;
#回报率(res-1.0);
返回值(random.random()-1.0)
课堂场景:
定义初始值(自身、宽度、高度):
全局渲染程序
全局渲染
全局tex_阵列
全球雨水缓冲区
全球液滴x偏移、液滴旋转速度、液滴下降速度
self.width=宽度
自我高度=高度
vs=GLuint(0)
fs=GLuint(0)
vs_源=“”
#版本410核心
int alien_索引中的布局(位置=0);
出局VS_出局
{
扁平内异形;
vec2tc;
}vs_out;
结构液滴
{
浮动x_偏移;
浮动y_偏移;
浮动方向;
未使用的漂浮物;
};
布局图(std140)均匀液滴
{
液滴[256];
};
真空总管(真空)
{
常数vec2[4]位置=vec2[4](vec2(-0.5,-0.5),
vec2(0.5,-0.5),
vec2(-0.5,0.5),
vec2(0.5,0.5));
vs_out.tc=位置[gl_VertexID].xy+vec2(0.5);
浮子co=cos(液滴[alien_index]。方向);
float so=sin(液滴[alien_index]。方向);
mat2 rot=mat2(vec2(co,so),
vec2(-so,co));
vec2位置=0.25*旋转*位置[gl_垂直方向];
gl_位置=vec4(位置x+液滴[外星索引])。x_偏移,
位置y+液滴[alien_索引].y_偏移,
0.5, 1.0);
vs_out.alien=alien_索引%64;
}
'''
fs_源=“”
#版本410核心
布局(位置=0)输出vec4颜色;
进进出出
{
扁平内异形;
vec2tc;
}财政司司长;
均匀采样阵列tex_;
真空总管(真空)
{
颜色=纹理(tex_异形,vec3(fs_in.tc,float(fs_in.异形));
}
'''
vs=glCreateShader(GLU顶点着色器)
glShaderSource(vs,vs_源)
glCompileShader(vs)
glGetShaderInfoLog(vs)
fs=glCreateShader(GL\u片段\u着色器)
glShaderSource(fs,fs_源)
glCompileShader(fs)
glGetShaderInfoLog(vs)
render_prog=glCreateProgram()
glAttachShader(渲染程序,vs)
glAttachShader(渲染程序,fs)
GLLINK程序(渲染程序)
glDeleteShader(vs)
glDeleteShader(fs)
glGetProgramInfoLog(渲染程序)
glGenVertexArrays(1,渲染)
glBindVertexArray(渲染)
ktxobj=KTXObject()
tex_alien_数组=ktxobj.ktx_加载(“aliens.ktx”)
glBindTexture(GL_纹理_2D_数组、tex_alien_数组)
glTexParameteri(GL_纹理_2D_数组、GL_纹理_最小_过滤器、GL_线性_MIPMAP_线性)
glGenBuffers(1,雨缓冲区)
glBindBuffer(GLU统一缓冲区、rain缓冲区)
glBufferData(GLU统一缓冲区,256*4*4,无,GLU动态绘图)
对于范围(0,256)内的i:
droplet_x_offset.append(随机浮点数()*2.0-1.0)
液滴旋转速度。附加((随机浮动()+0.5)*(-3.0如果(i&1)否则为3.0))
液滴下降速度附加(随机浮动()+0.2)
glBindVertexArray(渲染);
glEnable(GL_混合物);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_减去GL_SRC_ALPHA);
def显示(自):
全球雨水缓冲区
绿色=[0.0,0.1,0.0,0.0]
currentTime=time.time()
t=当前时间
glViewport(0,0,self.width,self.height)
glClearBufferfv(GL_颜色,0,绿色)
glUseProgram(渲染程序);
glBindBufferBase(GL_统一_缓冲区,0,rain_缓冲区);
droplet=glMapBufferRange(GL_统一_缓冲区,0,256*4*4,GL_映射_写入_位| GL_映射_无效_缓冲位)
float_数组=((ctypes.c_float*4)*256).from_地址(droplet)
对于范围(0,256)内的i:
浮点数组[i][0]=水滴x_偏移量[i]+2
浮点数组[i][1]=2.0-math.fmod((t+float(i))*水滴落下速度[i],4.31)*随机浮点()
浮点数组[i][2]=水滴旋转速度[i]*t*随机浮点()*math.pi
浮点数组[i][3]=0.0
glUnmapBuffer(GLU统一缓冲区);
对于范围(0,256)内的索引:
glVertexAttribI1i(0,外星指数);
gldrawArray(GL_三角带,0,4);
glutSwapBuffers()
def重塑(自身、宽度、高度):
self.width=宽度
自我高度=高度
def键盘(自动、按键、x、y):
全屏
全局多个立方体