Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Id de un vertice en GLSL ES

Iniciado por Daemon, 01 de Febrero de 2012, 07:11:54 PM

« anterior - próximo »

Daemon

Hola muy buenas a todo el mundo.

Soy muy novato en esto de los shaders y estoy haciendo un ejemplito para aclararme sobre como van. Se trata simplemente de modificar mediante un VertexShader ciertos vértices de una malla  conocidos de antemano, pero sólo estos. La versión que estoy empleando es la especificación de shaders que se utiliza en WebGL (GLSL ES).

El problema es que no encuentro la manera de pasar el id del vértice sobre el que se está ejecutando el shader actualmente.  En un VertexShader de GLSL existe el atributo gl_vertexID, pero no es así en la especificación GLSL ES ¿Sabéis si es posible pasar el id del vértice actual al shader y como hacerlo?

Muchas gracias.
Imagina todo lo que puedes hacer. Despues hazlo.

nostromo

Hola.

Creo, con el manual de OpenGL ES 2.0 en la mano, que gl_vertexID no existe en esta versión.
Porque no le pasas al vertex shader el atributo que te interese? Puedes pasarle los atributos por vertice que quieras.
Hay un pequeño limite (MAX_VERTEX_ATTRIBS) en el número de atributos que puedes pasar, pero en la practica no creo que tengas problema.

Saludos.

Daemon

Hola Nostromo.

Muchas gracias por tu respuesta. Quizás yo tenga algunos fallos fundamentales de concepto. A ver, lo que necesito es identificar a unos vértices concretos de la malla y no sé si por su posición se puede hacer, pues esta a priori va a ir cambiando conforme se ejecute la animación del modelo. Voy a cambiar la pregunta: ¿la posición de un vértice en una malla cambia cuando se realizan operaciones de traslación/rotación o la posición final es independiente de estas? Si fuera esto último sería sencillo, pues la identificación de los vértices ya nos vendría por su posición en la malla.

Independientemente de lo anterior lo que dices de pasarle los atributos al shader sería la solución, pero desgraciadamente no sé como seleccionar un vértice en concreto para establecerlos. Como ya dije, soy un novato completo, tengo muuucho que aprender y estoy en ello , o sea que se agradece de corazón vuestra paciencia :D.

Saludos.
Imagina todo lo que puedes hacer. Despues hazlo.

nostromo

Cita de: Daemon en 02 de Febrero de 2012, 10:04:40 AM
animación del modelo. Voy a cambiar la pregunta: ¿la posición de un vértice en una malla cambia cuando se realizan operaciones de traslación/rotación o la posición final es independiente de estas?

La posicion final del vertice que se calcula en el vertex shader es independiente de la posicion(el attribute posicion) de entrada al vertex shader.
Ahora bien, tu puedes cambiar las posiciones de entrada. Depende de lo que estés haciendo.

Cita de: Daemon en 02 de Febrero de 2012, 10:04:40 AM
Independientemente de lo anterior lo que dices de pasarle los atributos al shader sería la solución, pero desgraciadamente no sé como seleccionar un vértice en concreto para establecerlos. Como ya dije, soy un novato completo, tengo muuucho que aprender y estoy en ello , o sea que se agradece de corazón vuestra paciencia :D.

La cuestion es ¿como le estas pasando los "attributes" al shader? ¿Los estás pasando a mano con glVertexAttribPointer o estas usando una librería/engine?

Si los pasas a mano solo tienes que duplicar las llamadas que haces para pasar el attributo "posicion", suponiendo que se llame así.
Te pongo un ejemplo con los pasos para hacerlo a mano:

1. Crear un attributo nuevo en el shader, llamemosle "selected":
attribute bool selected;

2. Obtener el indice de este atributo del shader (Esto es C, en WebGL deberían haber llamadas similares):
    int selectedAttrib = getAttribLocation(shader, "selected");

3. Decirle a OpenGL donde están los valores de ese atributo:
    float VertexPositions[NUMERO_VERTICES*3];  //
    bool VertexSelected[NUMERO_VERTICES];  //  este es el nuevo array
    ....
    glVertexAttribPointer(selectedAttrib, 1, GL_BYTE, false, 0, VertexSelected );           
    glEnableVertexAttribArray(selectedAttrib);
    ...


Más o menos sería así hacerlo a mano en C. Aunque por las preguntas que has hecho, intuyo que estás usando una librería o un ejemplo de código que no entiendes.

Ten paciencia con este tema. Usar OpenGL ES 2.0 directamente, que es lo que se usa en WebGL, es difícil de aprender.





Daemon

Hola Nostromo.

Sí, estoy usando GLGE (una biblioteca bastante buena, por cierto), pero digamos que en ciertos puntos quiero emplear directamente javascript para crear un programa de OpenGL y un shader. Sobre lo que dices de pasar el atributo, ¿el valor de selected en el shader lo actualiza automáticamente OpenGL dependiendo del vértice que estemos actualmente empleando? Es decir, ¿opengl mueve automáticamente el índice del que toma el valor el atributo selected? Sí es así, genial, aparte me aclararía un montón de cosas :).
Imagina todo lo que puedes hacer. Despues hazlo.

nostromo

Cita de: Daemon en 03 de Febrero de 2012, 11:37:21 AM
Hola Nostromo.

Sí, estoy usando GLGE (una biblioteca bastante buena, por cierto), pero digamos que en ciertos puntos quiero emplear directamente javascript para crear un programa de OpenGL y un shader. Sobre lo que dices de pasar el atributo, ¿el valor de selected en el shader lo actualiza automáticamente OpenGL dependiendo del vértice que estemos actualmente empleando? Es decir, ¿opengl mueve automáticamente el índice del que toma el valor el atributo selected? Sí es así, genial, aparte me aclararía un montón de cosas :).

Si. A OpenGL se le pasan varios arrays o uno solo, depende de como te organices. Estos arrays, tienen la información por vértice de la posicion, normales, coordenadas de textura, y lo que quieras como en el caso de selected.

Supón que tenemos un shader con 2 atributos:

attribute float vec3 position;
attribute bool selected;
...



Lo que haces es asociar cada attribute del shader con un array(o buffer).
A OpenGL también le dices cuantos elementos del array hay por cada vértice. Ejemplo:
float VertexPositions[NUMERO_VERTICES*3]; 
En este array tenemos 3 elementos(floats) por vertice. Que son los floats para la posicion(x,y,z). En este caso pondriamos:
glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, false, 0, VertexPositions );      

Fijate que le decimos a OpenGL que el attribute position tiene 3 float.
Y hacemos lo mismo para selected. En este caso cada selected tendría 1 byte.

Luego cuando le decimos a OpenGL que dibuje triangulos:
glDrawArrays(GL_TRIANGLES, 0, NUMERO_VERTICES);

OpenGL coge 3 elementos de VertexPositions y los coloca en un atributo dentro del shader.

Para el atributo selected cogeria 1 elemento. Y así con todos los attributos.
Los arrays son de distinto tamaño pero tienen contenido para el mismo numero de vértices.

Tras "enviar" los attributos al shader. La GPU lo ejecuta. Y se repite lo mismo para el siguiente vertice.

Hay dos maneras de dibujar(draw) en OpenGL. Una manera es la que te he puesto aquí. Se trata de enviar la información de los vertices, y cada tres vértices consecutivos en los arrays se dibuja un triangulo. Digamos que con esta forma de hacerlo no se comparten los vertices entre triángulos.

Otra forma de dibujar es tener otro array que contiene indices a vértices. Estos indices tienen valor desde 0 hasta el numero de vértices que tengamos. 3 indices definen un triangulo.
Y le decimos a OpenGL que dibuje los triángulos a partir de estos indices. Esta segunda forma se hace llamando a glDrawElements.

Espero haberte aclarado este tema un poco.








Daemon

Sin duda lo has hecho, muchísimas gracias.
Imagina todo lo que puedes hacer. Despues hazlo.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.