代码之家  ›  专栏  ›  技术社区  ›  Jay Kominek

当输入glu点时,几何体着色器不会执行任何操作

  •  2
  • Jay Kominek  · 技术社区  · 14 年前

    我正在尝试使用几何体着色器将点转化为线段(GL\u points to GL\u line\u STRIP),但没有出现任何线段。如果我将输入更改为GL_线,然后重复顶点,那么我就得到了预期的行为。发生什么事?

    下面是一个完整的程序来演示这个行为。照现在的样子,我只有一扇黑色的窗户。设置USE\ POINTS为False会让我得到我期待的旋转迷幻闪烁线。

    #!/usr/bin/python
    
    from OpenGL.GL import *
    from OpenGL.GLU import *
    from OpenGL.GLUT import *
    from OpenGL.GL.ARB.geometry_shader4 import *
    from OpenGL.GL.EXT.geometry_shader4 import *
    
    import Image
    import numpy
    import numpy.linalg as linalg
    import random
    from math import sin, cos
    
    shader = None
    
    USE_POINTS = True
    
    def update(*args):
        glutTimerFunc(33, update, 0)
        glutPostRedisplay()
    
    def display():
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    
        t = glutGet(GLUT_ELAPSED_TIME)
        rot = t % (10 * 1000)
        theta = 2 * 3.141592 * (rot / 10000.0)
    
        glLoadIdentity()
        gluLookAt(-10*sin(theta), -10*cos(theta),   0,
                    0,   0,   0,
                    0,   0,   1)
    
        glUseProgram(shader)
        glUniform1f(glGetUniformLocation(shader, "distance"), rot/10000.0)
    
        # difference #1
        glBegin(GL_POINTS if USE_POINTS else GL_LINES)
        for x in [-2.5, 0, 2.5]:
            for y in [-2.5, 0, 2.5]:
                glVertexAttrib1f(7, random.uniform(0.0, 1.0))
                glVertexAttrib3f(0, x, y, 0)
                # difference #2
                if not USE_POINTS:
                    glVertexAttrib1f(7, random.uniform(0.0, 1.0))
                    glVertexAttrib3f(0, x, y, 0)
        glEnd()
        glUseProgram(0)
    
        glutSwapBuffers()
    
    def key(*args):
        if args[0] == '\x1b':
            sys.exit(0);
    
    def reshape(width, height):
        aspect = float(width)/float(height) if (height>0) else 1.0
        glViewport(0, 0, width, height)
    
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
    
        gluPerspective(45.0,
                       aspect,
                       1.0, 100.0)
    
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
    
        glutPostRedisplay()
    
    glutInit([])
    glutInitDisplayString("rgba>=8 depth>16 double")
    glutInitWindowSize(1280, 720)
    glutCreateWindow("Geometry Shader")
    
    glutDisplayFunc(display)
    glutReshapeFunc(reshape)
    glutKeyboardFunc(key)
    
    glutTimerFunc(33, update, 0)
    
    glEnable(GL_DEPTH_TEST)
    glEnable(GL_POINT_SMOOTH)
    glEnable(GL_LINE_SMOOTH)
    
    shader = glCreateProgram()
    vertex_shader = glCreateShader(GL_VERTEX_SHADER)
    geometry_shader = glCreateShader(GL_GEOMETRY_SHADER)
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER)
    
    # difference #3
    glProgramParameteriEXT(shader, GL_GEOMETRY_INPUT_TYPE_ARB, GL_POINTS if USE_POINTS else GL_LINES)
    glProgramParameteriEXT(shader, GL_GEOMETRY_OUTPUT_TYPE_ARB, GL_LINE_STRIP)
    glProgramParameteriEXT(shader, GL_GEOMETRY_VERTICES_OUT_ARB, 200)
    
    glAttachShader(shader, vertex_shader)
    glAttachShader(shader, geometry_shader)
    glAttachShader(shader, fragment_shader)
    
    glShaderSource(vertex_shader, """
    attribute float color;
    varying float geom_color;
    void main(void) {
      gl_Position = gl_Vertex;
      geom_color = color;
    }
    """)
    glCompileShader(vertex_shader)
    print glGetShaderInfoLog(vertex_shader)
    
    glShaderSource(geometry_shader, """
    #version 120
    #extension GL_EXT_geometry_shader4 : enable
    
    varying in float geom_color[1];
    varying out float frag_color;
    
    uniform float distance;
    
    void main(void)
    {
     int x, y;
    
     for(x=-1; x<=1; x+=1) {
       for(y=-1; y<=1; y+=1) {
         gl_Position = gl_PositionIn[0];
         gl_Position.x += x * distance;
         gl_Position.y += y * distance;
         gl_Position.z -= 2.0;
         gl_Position = gl_ModelViewProjectionMatrix * gl_Position;
         frag_color = geom_color[0];
         EmitVertex();
    
         gl_Position = gl_PositionIn[0];
         gl_Position.x += x * distance;
         gl_Position.y += y * distance;
         gl_Position.z += 2.0;
         gl_Position = gl_ModelViewProjectionMatrix * gl_Position;
         frag_color = geom_color[0];
         EmitVertex();
         EndPrimitive();
       }
     }
    }
    """)
    glCompileShader(geometry_shader)
    print glGetShaderInfoLog(geometry_shader)
    
    glShaderSource(fragment_shader, """
    varying float frag_color;
    void main(void) {
      gl_FragColor = vec4(frag_color,1.0-frag_color,frag_color,1);
    }
    """)
    glCompileShader(fragment_shader)
    print glGetShaderInfoLog(fragment_shader)
    
    glLinkProgram(shader)
    print glGetProgramInfoLog(shader)
    
    glBindAttribLocation(shader, 7, "color")
    
    glLinkProgram(shader)
    print glGetProgramInfoLog(shader)
    
    
    glutMainLoop()
    
    2 回复  |  直到 14 年前
        1
  •  1
  •   Mads Elvheim Mads Elvheim    14 年前

    我将代码与GL\u EXT\u geometry\u shader4规范进行了交叉检查,至少没有看到任何明显的错误。根据规范,所有的输入原语都与所有类型的输出原语一起工作。如果OpenGL没有通过glGetError返回错误,也没有着色器链接器/编译错误,那么我认为这是一个与ATI或pyOpenGL相关的问题。

    我敢肯定我已经测试了几何体着色器的输入和输出原语的大多数组合,它们都在我的Nvidia卡上工作。不过,我使用的是原生的C OpenGL库,而不是绑定。

        2
  •  0
  •   albert    12 年前

    刚才HD4850也有同样的问题。这看起来很奇怪,但问题确实有原因,可以解决。看来这和原来帖子的情况不一样。当其他人碰巧遇到类似情况时,请告知。

    原因来了。当“GL\u GEOMETRY\u INPUT\u TYPE\u ARB”设置为“GL\u POINTS”时,在几何体着色器代码中,有代码访问0以外的输入数组。

    顶点着色器

    in ivec4 vertex;
    flat out ivec4 v;
    

    几何渲染单元

    flat in ivec4 v[gl_VerticesIn];
    
    // somewhere in the code
       v[1].x ...