Last active
October 2, 2020 16:44
-
-
Save BioGeek/6c8f391bf4d1a2e2024f9480750072a1 to your computer and use it in GitHub Desktop.
Modify [quad.py](https://github.com/vispy/vispy/blob/master/examples/tutorial/gl/quad.py) to make it work offscreen with EGL background as in [offscreen.py](https://github.com/vispy/vispy/blob/master/examples/demo/gloo/offscreen.py).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
# ----------------------------------------------------------------------------- | |
# Copyright (c) Vispy Development Team. All Rights Reserved. | |
# Distributed under the (new) BSD License. See LICENSE.txt for more info. | |
# ----------------------------------------------------------------------------- | |
# Author: Nicolas P .Rougier | |
# Date: 04/03/2014 | |
# ----------------------------------------------------------------------------- | |
import numpy as np | |
import time | |
from vispy import app | |
from vispy.gloo import gl | |
from vispy.gloo.util import _screenshot | |
vertex_code = """ | |
uniform float scale; | |
attribute vec4 color; | |
attribute vec2 position; | |
varying vec4 v_color; | |
void main() | |
{ | |
gl_Position = vec4(scale*position, 0.0, 1.0); | |
v_color = color; | |
} """ | |
fragment_code = """ | |
varying vec4 v_color; | |
void main() | |
{ | |
gl_FragColor = v_color; | |
} """ | |
class Canvas(app.Canvas): | |
def __init__(self): | |
app.Canvas.__init__(self, show=False, size=(512, 512), title='Quad (GL)', | |
keys='interactive') | |
def on_initialize(self, event): | |
# Build data | |
self.data = np.zeros(4, [("position", np.float32, 2), | |
("color", np.float32, 4)]) | |
self.data['color'] = [(1, 0, 0, 1), (0, 1, 0, 1), | |
(0, 0, 1, 1), (1, 1, 0, 1)] | |
self.data['position'] = [(-1, -1), (-1, +1), | |
(+1, -1), (+1, +1)] | |
# Build & activate program | |
# Request a program and shader slots from GPU | |
program = gl.glCreateProgram() | |
vertex = gl.glCreateShader(gl.GL_VERTEX_SHADER) | |
fragment = gl.glCreateShader(gl.GL_FRAGMENT_SHADER) | |
# Set shaders source | |
gl.glShaderSource(vertex, vertex_code) | |
gl.glShaderSource(fragment, fragment_code) | |
# Compile shaders | |
gl.glCompileShader(vertex) | |
gl.glCompileShader(fragment) | |
# Attach shader objects to the program | |
gl.glAttachShader(program, vertex) | |
gl.glAttachShader(program, fragment) | |
# Build program | |
gl.glLinkProgram(program) | |
# Get rid of shaders (no more needed) | |
gl.glDetachShader(program, vertex) | |
gl.glDetachShader(program, fragment) | |
# Make program the default program | |
gl.glUseProgram(program) | |
# Build buffer | |
# Request a buffer slot from GPU | |
self._fbo = gl.glCreateBuffer() | |
# Make this buffer the default one | |
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._fbo) | |
# Upload data | |
gl.glBufferData(gl.GL_ARRAY_BUFFER, self.data, gl.GL_DYNAMIC_DRAW) | |
# Bind attributes | |
stride = self.data.strides[0] | |
offset = 0 | |
loc = gl.glGetAttribLocation(program, "position") | |
gl.glEnableVertexAttribArray(loc) | |
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._fbo) | |
gl.glVertexAttribPointer(loc, 3, gl.GL_FLOAT, False, stride, offset) | |
offset = self.data.dtype["position"].itemsize | |
loc = gl.glGetAttribLocation(program, "color") | |
gl.glEnableVertexAttribArray(loc) | |
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._fbo) | |
gl.glVertexAttribPointer(loc, 4, gl.GL_FLOAT, False, stride, offset) | |
# Bind uniforms | |
# -------------------------------------- | |
loc = gl.glGetUniformLocation(program, "scale") | |
gl.glUniform1f(loc, 1.0) | |
# We manually draw the hidden canvas. | |
self.update() | |
def on_draw(self, event): | |
gl.glClear(gl.GL_COLOR_BUFFER_BIT) | |
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4) | |
self.im = _screenshot((0, 0, self.size[0], self.size[1])) | |
# Immediately exit the application. | |
app.quit() | |
def on_resize(self, event): | |
gl.glViewport(0, 0, *event.physical_size) | |
if __name__ == '__main__': | |
start = time.time() | |
c = Canvas() | |
size = c.size | |
app.run() | |
# The rendering is done, we get the rendering output (4D NumPy array) | |
render = c.im | |
print('Finished in %.1fms.' % ( time.time() - start)) | |
# Now, we display this image with matplotlib to check. | |
import matplotlib.pyplot as plt | |
plt.figure(figsize=(size[0]/100., size[1]/100.), dpi=100) | |
plt.imshow(render, interpolation='none') | |
plt.savefig("quad.png") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment