TypeError:预期的c_float_Array_12_Array_3实例,得到了glm.vec3,seg错误

时间:2019-07-04 09:37:09

标签: python python-3.x opengl

如何解决一个错误,我正在尝试为glMapBufferRange分配的内存分配值,这是一个有问题的函数,因为在python中没有强制类型转换。我正在尝试为该内存分配值,尽管遇到标题中所述的错误。我还尝试过创建一个尺寸为np.array的{​​{1}},但无济于事。也许只是做不正确。

更新并成功!在Rabbid76的惊人帮助下,该修复程序首先分配并能够分配给material内存,然后再分配给sbmloader.py,程序成功渲染。谢谢。

最终结果也可以在我的github PythonOpenGLSuperBible7Glut

上找到

支持文件:hdrbloom_support.zip

期望的输出渲染是实际结果的渲染:

expected output rendering

源代码:

glMapBufferRange

移植自:hdrbloom.cpp,《 Superbible Opengl》第7版。 p.490

1 个答案:

答案 0 :(得分:1)

首先请注意,(std140)结构在统一块中的内存布局

  
struct material_t
{
   vec3    diffuse_color;
   vec3    specular_color;
   float   specular_power;
   vec3    ambient_color;
};

diffuse_color  : 3 floats (x, y, z), 1 float  alignment
specular_color : 3 floats (x, y, z),
specular_power : 1 float,            
ambient_color  : 3 floats (x, y, z), 1 float  alignment

请阅读Should I ever use a vec3 inside of a uniform buffer or shader storage buffer object?
并参见OpenGL 4.6 API Core Profile Specification; 7.6.2.2 Standard Uniform Block Layout,第144页。

因此,缓冲区的大小为12 * ctypes.sizeof(ctypes.c_float)

size_material = ctypes.sizeof(ctypes.c_float) * 12;

为统一块数组创建缓冲区:

  
layout (binding = 1, std140) uniform MATERIAL_BLOCK
{
   material_t  material[32];
} materials;
glBufferData(GL_UNIFORM_BUFFER, SPHERE_COUNT * size_material, None, GL_STATIC_DRAW)

将形状为({SPHERE_COUNT,12)的二维数组映射到缓冲存储器:

mat = glMapBufferRange(GL_UNIFORM_BUFFER, 0, SPHERE_COUNT * size_material, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT)
m = (GLfloat * 12 * SPHERE_COUNT).from_address(mat)

通过数组分配在循环中分配值:

ambient = 0.002
for i in range(SPHERE_COUNT):

    fi = 3.14159267 * i / 8.0

    m[i][0:3]  = (ctypes.c_float * 3)(sin(fi) * 0.5 + 0.5, sin(fi + 1.345) * 0.5 + 0.5, sin(fi + 2.567) * 0.5 + 0.5)
    m[i][4:7]  = (ctypes.c_float * 3)(2.8, 2.8, 2.9)
    m[i][7]    = 30
    m[i][8:11] = (ctypes.c_float * 3)(ambient * 0.025, ambient * 0.025, ambient * 0.025)

    ambient *= 1.5

第二个统一块的大小

  
layout (binding = 0, std140) uniform TRANSFORM_BLOCK
{
   mat4    mat_proj;
   mat4    mat_view;
   mat4    mat_model[32];
} transforms;

size_transforms_t = glm.sizeof(glm.mat4) * (SPHERE_COUNT+2)

将形状为(SPHERE_COUNT+2),16)的二维数组映射到缓冲存储器:

mbuffer = glMapBufferRange(GL_UNIFORM_BUFFER, 0, size_transforms_t, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT)
bufferp = (GLfloat * 16 * (SPHERE_COUNT+2)).from_address(mbuffer)

SBMObject.render_sub_object不会渲染实例。它一定是这样的:

 def render_sub_object(self, object_index, instance_count, base_instance):
        global index_type

        glBindVertexArray(self.vao)

        if instance_count == 0:
            glDrawArrays(GL_TRIANGLES, 0, self.vertexcount)
        else:
            glDrawArraysInstancedBaseInstance(GL_TRIANGLES,
                                               0,
                                               self.vertexcount,
                                               instance_count,
                                               base_instance)

        # [...]

show_prefiltershow_bloomshow_scene是布尔值,它们永远不会等于0.0。均匀的float bloom_factorfloat scene_factor必须较粗,然后为0.0,否则片段的颜色为黑色。

glUniform1f(uniforms.resolve.bloom_factor, bloom_factor if show_bloom==0 else 0.0)
glUniform1f(uniforms.resolve.scene_factor, 1.0 if show_scene==0 else 0.0)
glUniform1f(uniforms.resolve.bloom_factor, bloom_factor if show_bloom else 0.0)
glUniform1f(uniforms.resolve.scene_factor, 1.0 if show_scene else 0.0 )

glBindTexture(GL_TEXTURE_2D, tex_brightpass if show_prefilter==0 else tex_scene)
glBindTexture(GL_TEXTURE_2D, tex_brightpass if show_prefilter else tex_scene)