微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

glfw 屏幕外和大图像窗口渲染之间的不同结果

如何解决glfw 屏幕外和大图像窗口渲染之间的不同结果

我在使用 glfw 窗口和离屏渲染时得到了不同的结果。我想在网格上使用此 texture_image 应用纹理映射。图片尺寸为 3500 x 1752。

我在弹出的glfw窗口上渲染和显示渲染图像的代码如下:

t_obj = "mesh.obj"
tex_file_path = "texture.png"

tex_im = cv2.imread(tex_file_path)
h,w = tex_im.shape[:2]
vertices,tex_coords,indices = load_obj_file(t_obj,dimension=3)
colors = np.ones((len(vertices),3),dtype=np.float)

vertices = np.hstack((vertices,colors,tex_coords))
vertices = np.array(vertices,dtype=np.float32)

# a vertex shader consists of x,y,z and w.
vertex_src = """
# version 330
layout(location = 0) in vec3 a_position;
layout(location = 1) in vec3 a_color;
layout(location = 2) in vec2 a_texture;
uniform mat4 rotation;
out vec3 v_color;
out vec2 v_texture;
void main()
{
    gl_Position = rotation * vec4(a_position,1.0);
    v_color = a_color;
    v_texture = a_texture;

    //v_texture = 1 - a_texture;                      // Flips the texture vertically and horizontally
    //v_texture = vec2(a_texture.s,1 - a_texture.t); // Flips the texture vertically
}
"""

# fragment shader consists of R,G,B and A.
fragment_src = """
# version 330
in vec3 v_color;
in vec2 v_texture;
out vec4 out_color;
uniform sampler2D s_texture;
void main()
{
    out_color = texture(s_texture,v_texture) * vec4(v_color,1.0f);
}
"""


# glfw callback functions
def window_resize(window,width,height):
    glViewport(0,height)


# initializing glfw library
if not glfw.init():
    raise Exception("glfw can not be initialized!")

# creating the window
# glfw.window_hint(glfw.VISIBLE,glfw.FALSE)
window = glfw.create_window(w,h,"My OpenGL window",None,None)

# check if window was created
if not window:
    glfw.terminate()
    raise Exception("glfw window can not be created!")

# set window's position
glfw.set_window_pos(window,w,h)

# set the callback function for window resize
glfw.set_window_size_callback(window,window_resize)

# make the context current
glfw.make_context_current(window)

shader = compileProgram(compileShader(vertex_src,GL_VERTEX_SHADER),compileShader(fragment_src,GL_FRAGMENT_SHADER))

# Step2: Create and bind VBO objects to transfer data
VBO = glGenBuffers(1)  # request a buffer slot from GPU.
glBindBuffer(GL_ARRAY_BUFFER,VBO)  # make this buffer the default one.
glBufferData(GL_ARRAY_BUFFER,vertices.nbytes,vertices,GL_STATIC_DRAW)  # upload cpu data to GPU buffer.

# Step3: Create and bind EBO object to transfer data
EBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER,indices.nbytes,indices,GL_STATIC_DRAW)
# Step4: Specify the resolution method and enable vertex attributes
glEnabLevertexAttribArray(0)
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,vertices.itemsize * 8,ctypes.c_void_p(0))
# Vertex color attributes
glEnabLevertexAttribArray(1)
glVertexAttribPointer(1,ctypes.c_void_p(12))
# Vertex texture attributes
glEnabLevertexAttribArray(2)
glVertexAttribPointer(2,2,ctypes.c_void_p(24))

texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D,texture)

# Set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT)
# Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR)

# load image
image = Image.open(tex_file_path)
image = image.transpose(Image.FLIP_TOP_BottOM)
img_data = image.convert("RGBA").tobytes()
# Attach a texture image to the texture buffer.
glTexImage2D(GL_TEXTURE_2D,GL_RGBA,image.width,image.height,GL_UNSIGNED_BYTE,img_data)

gluseProgram(shader)
glClearColor(1,1,1)
glEnable(GL_DEPTH_TEST)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)

model = pyrr.matrix44.create_from_translation(pyrr.Vector3([0.0,0.0,0]))
rotation_loc = glGetUniformlocation(shader,"rotation")

# the main application loop
while not glfw.window_should_close(window):
    glfw.poll_events()
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    gluniformMatrix4fv(rotation_loc,model)
    glDrawElements(GL_TRIANGLES,len(indices),GL_UNSIGNED_INT,None)

    glfw.swap_buffers(window)

# save_image
data = glreadPixels(0,GL_UNSIGNED_BYTE)
pil_image = Image.frombytes("RGBA",(w,h),data)
pil_image = ImageOps.flip(pil_image)
pil_image.save('output.png')
glfw.terminate()

结果是with_popup_window_result

但是,保存到磁盘的输出图像被调整为较小的图像,然后进行填充,以便最终的宽度和高度与纹理图像的宽度和高度相同。这是saved_output

但是,如果我修改代码使其进行离屏渲染并且不显示 glfw 窗口,则会裁剪输出图像。修改后的代码如下:

t_obj = "obj_time_0.5.obj"
tex_file_path = "s.png"

tex_im = cv2.imread(tex_file_path)
h,height)


# initializing glfw library
if not glfw.init():
    raise Exception("glfw can not be initialized!")

# creating the window
glfw.window_hint(glfw.VISIBLE,"rotation")

# the main application loop
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

gluniformMatrix4fv(rotation_loc,model)
glDrawElements(GL_TRIANGLES,None)

# save_image
data = glreadPixels(0,data)
pil_image = ImageOps.flip(pil_image)
pil_image.save('output.png')
glfw.destroy_window(window)
glfw.terminate()

此离屏渲染的保存结果为 offscreen_output。它被裁剪和填充,因此生成的图像尺寸不会改变。

我想知道是什么导致了这些调整大小和裁剪问题。这只发生在输出维度很大的时候。我尝试将较小的尺寸 (glreadPixels() 并且输出图像很好(没有调整大小或裁剪)。我在某处读到有人可以尝试使用 frameBufferObject (FBO) 进行离屏渲染而不是使用 glfw 但由于我不知道如何使用 FBO,当我从某人那里复制 FBO 代码时程序崩溃了其他的。

非常感谢任何帮助。预先非常感谢您。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。