简体   繁体   中英

Using Visuals with gloo shader programs in Vispy

I'm trying to overlay some TextVisuals over my scene, but I'm having trouble getting everything to show properly. Here is my code which is slightlty modified from the vispy example here

import numpy as np

from vispy import app, gloo, visuals
from vispy.gloo import Program, VertexBuffer, IndexBuffer
from vispy.util.transforms import perspective, translate, rotate
from vispy.geometry import create_cube


vertex = """
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
attribute vec3 position;
attribute vec2 texcoord;
attribute vec3 normal;
attribute vec4 color;
varying vec4 v_color;
void main()
{
    v_color = color;
    gl_Position = projection * view * model * vec4(position,1.0);
}
"""

fragment = """
varying vec4 v_color;
void main()
{
    gl_FragColor = v_color;
}
"""

vertexcb = """
attribute vec2 position;
void main()
{
    gl_Position = vec4(position, 0.0, 1.0);
}

"""

fragmentcb = """
uniform vec2 screen;

void main()
{
    float color = (gl_FragCoord.x-0.1*screen.x)/(0.8*screen.x);
    gl_FragColor = vec4(0.0416+max(min(2.625106*color,0.9584),0),max(min(2.624996*color-0.958331,1),0),0.1+max(min(3.937504*color-2.937504,0.9),0),0);
}
"""

class Canvas(app.Canvas):
    def __init__(self):
        app.Canvas.__init__(self, size=(800, 600), title='Colored cube',
                            keys='interactive')

        # Build cube data
        V, I, _ = create_cube()
        vertices = VertexBuffer(V)
        self.indices = IndexBuffer(I)

        # Build program
        self.program = Program(vertex, fragment)
        self.program.bind(vertices)

        # Build view, model, projection & normal
        view = translate((0, 0, -5))
        model = np.eye(4, dtype=np.float32)
        self.program['model'] = model
        self.program['view'] = view
        self.phi, self.theta = 0, 0

        # Add colorbar
        self.programcb = Program(vertexcb, fragmentcb)
        self.programcb['screen'] = self.physical_size        
        self.programcb['position'] = [[-0.8, -0.8],[-0.8,-0.6],[0.8,-0.8],[0.8,-0.6]]
        self.indicescb = IndexBuffer([[0,1,2],[1,2,3]])

        # Add text
        self.testText = visuals.TextVisual('Testy',pos=(20,20))
        self.tr_sys = visuals.transforms.TransformSystem(self)   

        gloo.set_state(clear_color=(0.30, 0.30, 0.35, 1.00), depth_test=True)

        self.activate_zoom()

        self.timer = app.Timer('auto', self.on_timer, start=True)

        self.show()

    def on_draw(self, event):
        gloo.clear(color=True, depth=True)
        self.testText.draw(self.tr_sys) #draw text
        self.program.draw('triangles', self.indices) #draw the cube
        self.programcb.draw('triangles', self.indicescb) # draw the colorbar


    def on_resize(self, event):
        self.activate_zoom()

    def activate_zoom(self):
        gloo.set_viewport(0, 0, *self.physical_size)
        self.programcb['screen'] = self.physical_size
        projection = perspective(45.0, self.size[0] / float(self.size[1]),
                                 2.0, 10.0)
        self.program['projection'] = projection

    def on_timer(self, event):
        self.theta += .5
        self.phi += .5
        self.program['model'] = np.dot(rotate(self.theta, (0, 0, 1)),
                                       rotate(self.phi, (0, 1, 0)))
        self.update()

if __name__ == '__main__':
    c = Canvas()
    app.run()

This produces a scene with a rotating cube and text, but the colorbar is missing. In addition some faces of the cube show only the inside of that triangle. When I remove self.testText.draw(self.tr_sys) from on_draw method, both the colorbar and the cube show correctly. If I comment out the cube drawing and leave the colorbar and text drawing, I' only get the text.

What is happening here? Is the TransformSystem somehow changing the location of colorbar, in a way that VertexBuffer knows how to handle, so that the cube is still shown? The code is also much slower when both the text and the broken cube are showing, compared to the cube and colorbar. Is the text drawing changing some OpenGL settings which causes slowdowns?

Here's the scene with nothing commented out 带有文字的场景

The scene without text 没有文字

The text rendering code is probably disabling the depth test and your cube drawing code doesn't (re-)enable it.

The line

gloo.set_state(clear_color=(0.30, 0.30, 0.35, 1.00), depth_test=True)

does enable depth testing, but its set only in the constructor. Here's an important rule (speak with me): There is no "initialization" in OpenGL. There's just state, which must be set when needed, right before it's needed to what it is needed to be. Add this

right before the cube triangle drawing code, ie

def on_draw(self, event): gloo.clear(color=True, depth=True) self.testText.draw(self.tr_sys) #draw text

    gloo.set_state(depth_test=True)
    self.program.draw('triangles', self.indices) #draw the cube

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM