如何解决一个错误,我正在尝试为glMapBufferRange
分配的内存分配值,这是一个有问题的函数,因为在python中没有强制类型转换。我正在尝试为该内存分配值,尽管遇到标题中所述的错误。我还尝试过创建一个尺寸为np.array
的{{1}},但无济于事。也许只是做不正确。
更新并成功!在Rabbid76的惊人帮助下,该修复程序首先分配并能够分配给material
内存,然后再分配给sbmloader.py,程序成功渲染。谢谢。
最终结果也可以在我的github PythonOpenGLSuperBible7Glut
上找到支持文件:hdrbloom_support.zip
期望的输出渲染是实际结果的渲染:
源代码:
glMapBufferRange
移植自:hdrbloom.cpp,《 Superbible Opengl》第7版。 p.490
答案 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_prefilter
,show_bloom
和show_scene
是布尔值,它们永远不会等于0.0。均匀的float bloom_factor
或float 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)