I wrote this simple program that displays an image onto a moderngl context, using pygame, and my goal is to draw a rectangle on the screen. (This is obviously just a minimal working example, and the real goal is to animate the texture and make more than a rectangle on the screen).
import moderngl
import numpy as np
import pygame
from PIL import Image
class MyPyGame:
def __init__(self):
pygame.init()
self._surface = pygame.display.set_mode((800, 600), pygame.DOUBLEBUF | pygame.OPENGL)
self.context = moderngl.create_context()
image = Image.open("test.jpg").transpose(Image.FLIP_TOP_BOTTOM)
self.texture = self.context.texture(image.size, 3, image.tobytes())
self.texture.use(0)
self.program = self.context.program(
vertex_shader="""
#version 330
in vec2 in_position;
out vec2 uv0;
void main() {
gl_Position = vec4(in_position, 0.0, 1.0);
uv0 = (0.5 * in_position) + vec2(0.5);
}
""",
fragment_shader="""
#version 330
out vec4 fragColor;
uniform sampler2D texture0;
in vec2 uv0;
void main() {
fragColor = texture(texture0, uv0);
}
""")
vertices_quad_2d = np.array([-1.0, 1.0, -1.0, -1.0, 1.0, -1.0,
-1.0, 1.0, 1.0, -1.0, 1.0, 1.0], dtype=np.float32)
vertex_buffer_quad_2d = self.context.buffer(vertices_quad_2d.tobytes())
self.vertex_array = self.context.vertex_array(self.program, [(vertex_buffer_quad_2d, "2f", "in_position")])
def run(self):
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
self.vertex_array.render()
pygame.display.flip()
if __name__ == '__main__':
app = MyPyGame()
app.run()
Some things I tried:
Draw a rectangle as is the "regular" way with
pygame, that is, add this line in the mainrunmethod, either before or after the vertex array rendering (both didn't work):pygame.draw.rect(self._surface, (200, 200, 200), [100, 100, 100, 100])Instead of flag
pygame.OPENGL, use flagpygame.OPENGLBLITand thenblitthe rectangle (didn't work, more info here)Use the
modernglcontext as a window inside the main display, as suggested here, and thenblitthe rectangle onto the main display. This is not what I am aiming for, I want to able to display texts and shapes onto the context, but still, wanted to at least try this. Didn't work either, the code below (replacing the corresponding code in the__init__) resulted in an exceptioncannot detect OpenGL context:pygame.init() self.main_window = pygame.display.set_mode((800, 600)) self.graphics_window = pygame.Surface((700, 600), pygame.DOUBLEBUF | pygame.OPENGL) self.main_window.blit(self.graphics_window, (100, 0)) self.context = moderngl.create_context()Use "out of the box" window from
moderngl_windowusingpygame(code here). Again, didn't succeed to draw a rectangle onto the context itself - tried to add the same line from (1) either inside the window code itself, or when I write my own window that inherits from this pygame window.
[Working on: Windows10, python3.6, pygame 1.9.6, moderngl 5.6.1]
How can I create a window that is both displaying graphics and has a layer of costume objects? (text, buttons, etc.)
EDIT: Perhaps a clarification for my motivation is needed: I would like to have one layer of graphics in the background, that in the example above is some manipulation of an input image. Then, in the foreground, I would like to have some costume PyGame objects like geometric shapes, buttons, etc.