2

ジオメトリシェーダーを使用してポイントをラインセグメント(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()
4

2 に答える 2

1

コードを GL_EXT_geometry_shader4 仕様と照合しましたが、少なくとも明らかなエラーは見られません。仕様によると、すべての入力プリミティブはすべてのタイプの出力プリミティブで機能します。OpenGL が glGetError を介してエラーを返さず、シェーダー リンカー/コンパイル エラーも返さない場合、これは ATI または pyOpenGL 関連の問題であると言えます。

ジオメトリ シェーダーの入力プリミティブと出力プリミティブのほとんどの組み合わせをテストしたと確信しており、それらはすべて Nvidia カードで動作します。ただし、バインディングではなく、ネイティブの C OpenGL ライブラリを使用します。

于 2010-10-25T16:05:11.463 に答える
0

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 は「頂点」属性で失敗します。

于 2012-05-21T14:58:01.123 に答える