几何着色器在输入 GL_POINTS 时不会执行任何操作

发布于 2024-09-28 00:49:28 字数 4266 浏览 3 评论 0原文

我试图使用几何着色器将点转换为线段(GL_POINTS 到 GL_LINE_STRIP),但没有出现线段。如果我将输入更改为 GL_LINES,然后重复顶点,那么我就会得到我期望的行为。这是怎么回事?

这是演示该行为的完整程序。按原样,我除了一个黑色的窗口之外什么也没有。将 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()

I'm trying to use geometry shaders to turn points into line segments (GL_POINTS to GL_LINE_STRIP), but no line segments appear. If I change the input to GL_LINES, and just repeat the vertex, then I get the behavior I'm expecting. What's going on?

Here's a complete program that demonstrates the behavior. As-is, I get nothing but a black window. Setting USE_POINTS to False gets me the rotating psychedelic flashing lines I'm expecting.

#!/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()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤蝉 2024-10-05 00:49:28

我用 GL_EXT_geometry_shader4 规范交叉检查了代码,至少没有看到任何明显的错误。根据规范,所有输入原语都适用于所有类型的输出原语。如果 OpenGL 通过 glGetError 没有返回错误,并且没有着色器链接器/编译错误,我会说这是 ATI 或 pyOpenGL 相关的问题。

我相当确定我已经测试了几何着色器的输入和输出基元的大多数组合,并且它们都可以在我的 Nvidia 卡上工作。不过,我使用本机 C OpenGL 库,而不是绑定。

I cross-checked the code with the GL_EXT_geometry_shader4 specification, and I don't see any obvious errors at least. According to the specification, all input primitives work with all types of output primitives. If OpenGL returns no errors via glGetError, and no shader linker/compilation errors, I'd say this is an ATI or pyOpenGL-related issue.

I'm fairly sure I've tested most combinations of input and output primitives for geometry shaders, and they all work on my Nvidia card. I use the native C OpenGL libraries though, not a binding.

一身仙ぐ女味 2024-10-05 00:49:28

我刚刚用HD4850也遇到同样的问题。这看起来很奇怪,但问题确实有原因并且可以解决。看来这和原帖的情况不太一样。仅供参考,当其他人碰巧到达此帖子时,由于类似情况而被阻止。

原因就在这里。当 GL_GEOMETRY_INPUT_TYPE_ARB 设置为 GL_POINTS 时,在几何着色器代码中,有代码访问超过 0 的输入数组。

顶点

in ivec4 vertex;
flat out ivec4 v;

着色器

flat in ivec4 v[gl_VerticesIn];

// somewhere in the code
   v[1].x ...

几何着色器 编译/链接一切正常,但 glGetAttribLocationARB 对于“顶点”属性失败。

I got the same problem just now with HD4850. It seems weird but the problem really has a cause and can be resolved. It looks like this is not the same situation as the original post. Just FYI when someone else happens to reach this post blocked by similar situations.

Here goes the cause. When GL_GEOMETRY_INPUT_TYPE_ARB is set to GL_POINTS, in the geometry shader code, there is code accessing the input array beyond 0.

Vertex Shader

in ivec4 vertex;
flat out ivec4 v;

Geometry Shader

flat in ivec4 v[gl_VerticesIn];

// somewhere in the code
   v[1].x ...

Everything goes fine with compile/link, but glGetAttribLocationARB fails for the "vertex" attribute.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文