2011-05-16 10 views
18

glLineStipple ha quedado obsoleto en las últimas API de OpenGL. ¿Con qué se reemplaza? Si no se reemplaza, ¿cómo puedo obtener un efecto similar? (No quiero usar un perfil de compatibilidad, por supuesto ...)glLineStipple obsoleto en OpenGL 3.1

+0

No realmente abandonado, aprender y jugar con OpenGL es un hobby, y en realidad tengo muy poco tiempo para eso. ¡Pero con mucho gusto votaré tu respuesta! – Vincent

Respuesta

22

Lo sentimos, no ha sido reemplazado por nada. La primera idea que me viene a la mente para emularlo sería el sombreador de geometría. Alimenta el sombreador de geometría con una línea, calcula la longitud de su espacio de pantalla y, en función de eso, genera un número variable de sublíneas entre sus vértices de inicio y fin.


EDIT: Tal vez también se puede utilizar una textura 1D con el alfa (o rojo) canal que codifica el patrón como 0,0 (sin línea) o 1,0 (línea) y, a continuación tienen las líneas de coordenadas de textura ir desde 0 a 1 y en el fragmento de fragmentos haces una prueba alfa simple, descartando fragmentos con alfa por debajo de un umbral. Puede facilitar el sombreado de geometría para generar su línea texCoords, ya que de lo contrario necesita diferentes vértices para cada línea. De esta manera, también puede hacer que texCoord dependa de la longitud del espacio de la pantalla de la línea.

Todo se vuelve más difícil si dibujas triángulos (usando el modo de polígono GL_LINE). Luego tiene que hacer la transformación de triángulo en el sombreador de geometría, colocar triángulos y poner líneas (eso también podría ser una razón para desaprobar el modo de polígono en el futuro, si no lo ha hecho).


EDIT: Aunque creo que esta pregunta abandomned, he hecho un shader sencilla triple para el segundo enfoque. Es solo una solución mínima, puede agregar funciones personalizadas usted mismo. Yo no lo he probado porque me falta el hardware lo necesite, pero usted debe conseguir el punto:

uniform mat4 modelViewProj; 

layout(location=0) in vec4 vertex; 

void main() 
{ 
    gl_Position = modelViewProj * vertex; 
} 

El vertex shader es un simple pase a través.

layout(lines) in; 
layout(line_strip, max_vertices=2) out; 

uniform vec2 screenSize; 
uniform float patternSize; 

noperspective out float texCoord; 

void main() 
{ 
    vec2 winPos0 = screenSize.xy * gl_in[0].gl_Position.xy/gl_in[0].gl_Position.w; 
    vec2 winPos1 = screenSize.xy * gl_in[1].gl_Position.xy/gl_in[1].gl_Position.w; 
    gl_Position = gl_in[0].gl_Position; 
    texCoord = 0.0; 
    EmitVertex(); 
    gl_Position = gl_in[1].gl_Position; 
    texCoord = 0.5 * length(winPos1-winPos0)/patternSize; 
    EmitVertex(); 
} 

En el sombreador de geometría tomamos una línea y calculamos la longitud de su espacio de pantalla en píxeles. A continuación, devidemos esto por el tamaño de la textura del patrón de punteado, que sería factor*16 al emular una llamada al glLineStipple(factor, pattern). Esto se toma como una coordenada de textura 1D del punto final de la segunda línea.

Tenga en cuenta que esta coordenada de textura debe ser interpolada linealmente (noperspective especificador de interpolación). La interpolación perpective correcta correcta ocasionaría que el patrón de punteado a "se apriete" en partes más alejadas de la línea, mientras que explícitamente trabajamos con valores de espacio de pantalla.

uniform sampler1D pattern; 
uniform vec4 lineColor; 

noperspective in float texCoord; 

layout(location=0) out vec4 color; 

void main() 
{ 
    if(texture(pattern, texCoord).r < 0.5) 
     discard; 
    color = lineColor; 
} 

El shader fragmento ahora sólo realiza una prueba alfa simple usando el valor de la textura de patrón, que contiene un 1 por línea y un 0 para ninguna línea. Por lo tanto, para emular el punteado de función fija tendría una textura 1D de 1 componente de 16 píxeles en lugar de un patrón de 16 bits. No se olvide de configurar el modo de ajuste del patrón en GL_REPEAT, sobre el modo de filtrado, no estoy tan seguro, pero supongo que GL_NEAREST sería una buena idea.

Pero como se dijo anteriormente, si desea representar triángulos con glPolygonMode, no funcionará de esta manera. En su lugar, debe adaptar el sombreador de geometría para aceptar triángulos y generar 3 líneas para cada triángulo.


EDIT: De hecho OpenGL apoyo directo de 3 para las operaciones de enteros en los shaders nos permite caer por completo todo este planteamiento 1D-textura y trabajamos recta hacia adelante con un patrón de bits real. Así, el shader de geometría se cambia ligeramente para apagar coordinar el patrón real de la pantalla de tamaño, sin normalización:

texCoord = 0.5 * length(winPos1-winPos0); 

En el shader fragmento que luego tomar un patrón de bits como un número entero sin signo (aunque de 32 bits en contraste con glLineStipple 's 16-bit value) y el factor de estiramiento del patrón y simplemente toma la textura de la textura (bueno, ninguna textura más en realidad, pero no importa) módulo 32 para obtener su posición en el patrón (los explícitos uint s son molestos, pero mi compilador GLSL dice que las conversiones implícitas entre int y uint son malas):

uniform uint pattern; 
uniform float factor; 

... 
uint bit = uint(round(linePos/factor)) & 31U; 
if((pattern & (1U<<bit)) == 0U) 
    discard; 
+0

Big thx para su repetición! Es genial y en profundidad. –

+2

Impresionante. ¿Pero se puede hacer sin un sombreador de geometría en OpenGLES-2? – Bram

+0

@Bram Sí. No he usado el sombreador de geometría para generar nuevas primitivas, solo para calcular las coordenadas de textura de la línea en función de la longitud del espacio de la pantalla. Puede hacerlo sin un GS, pero en este caso tendrá que calcular los texCoords en la CPU. Pero esto significa que tienes que duplicar los vértices, ya que cada vértice necesita un texCoord diferente para cada línea y no puedes hacer que dependa del tamaño del espacio de pantalla tan fácilmente (bueno, aún puedes calcular su longitud de espacio de pantalla en la CPU, pero cada cuadro?). No se puede hacer en el VS, ya que solo se ve un vértice y no toda la línea. –