0

I'm running into a very strange issue with moderngl latest version when running in headless mode. The following code should give me a triangle that touches the edges of the viewport on the right and on the top, but instead the right and top vertices extend outside the viewport by some odd factor of 1.98 or so. Changing the x- and y values to say 0.5 does not alter the output. This is the same on OSX and Linux. Does anyone have any idea what's going on here??

import moderngl
from pyrr import Matrix44
import numpy as np
import cv2

vertex_shader_source = """
    #version 330
    in vec3 local_vertex;
    uniform mat4 modelview_matrix;
    uniform mat4 projection_matrix;
    void main(){
        gl_Position = projection_matrix * modelview_matrix * vec4( local_vertex, 1.0 );
    }
"""

fragment_shader_source = """
    #version 330
    out vec4 out_color;
    void main() {
        out_color = vec4(1.0, 1.0, 1.0, 1.0);
    }
"""

context = moderngl.create_standalone_context()
prog = context.program(vertex_shader=vertex_shader_source, fragment_shader=fragment_shader_source)

vertices = np.array([[ 0.0,  0.0, 0.0],
                        [ 1.0,  0.0, 0.0],
                        [ 1.0,  1.0, 0.0]])

vbo = context.buffer(vertices.tobytes())
vao = context.simple_vertex_array(prog, vbo, "local_vertex")
color_renderbuffer = context.renderbuffer((128, 128))
fbo_regular = context.framebuffer(color_attachments=(color_renderbuffer))

modelview_matrix = Matrix44.look_at(np.array([0.0, 0.0, 10.0]), np.array([0.0, 0.0, 0.0]), np.array([0.0, 1.0, 0.0]))
projection_matrix = Matrix44.orthogonal_projection(-1.0, 1.0, -1.0, 1.0, 1.0, 100.0)
prog["projection_matrix"].write(projection_matrix.astype("f4").tobytes())
prog["modelview_matrix"].write(modelview_matrix.astype("f4").tobytes())

fbo_regular.use()
context.clear(1.0, 0.0, 0.0)
vao.render()

data = fbo_regular.read(components=3, alignment=1, dtype='f4')
data_array = np.frombuffer(data, dtype=np.float32).reshape(128,128,3)
cv2.imwrite("output0.png",(data_array[::-1]) * 255.0)

the output is: Text

UPDATE: apparently, when I use the 'struct' module, the problem goes away.

self.vbo = self.ctx.buffer(struct.pack('9f', 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0))

what gives??

Jochemspek
  • 321
  • 2
  • 9

2 Answers2

1

Numpy is using 64 bit floats by default so the in vec3 local_vertex in your vertex shader gets a bit confused. See : https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)

# The most efficient way is to construct the array using the right dtype
self.vertices = np.array([[ 0.0,  0.0, 0.0],
                          [ 1.0,  0.0, 0.0],
                          [ 1.0,  1.0, 0.0]], dtype='f4')

# Because both numpy and moderngl supports the buffer protocol
# we can pass them directly instead of converting to `bytes`
self.vbo = self.ctx.buffer(self.vertices)

If you have problems with moderngl you can also reach out to the moderngl community : https://github.com/moderngl/moderngl

Grimmy
  • 3,992
  • 22
  • 25
0

soved it, by casting the numpy buffer astype f4:

self.vertices = np.array([[ 0.0,  0.0, 0.0],
                          [ 1.0,  0.0, 0.0],
                          [ 1.0,  1.0, 0.0]])

self.vbo = self.ctx.buffer(self.vertices.astype('f4'))

gives the expected result. The default datatype for a numpy array of floats is f8 (64 bit double), the vertex buffer expects 32 bits. this just so happens to give similar results which threw me off.

Jochemspek
  • 321
  • 2
  • 9