Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Limitar El Viewport Con Forma No Rectangular

Iniciado por tamat, 11 de Abril de 2004, 04:55:15 PM

« anterior - próximo »

tamat

 Estoy haciendo mi propio sistema GUI 2D y aunque por el momento lo uso todo en 2D tengo pensado que en el futuro se pueda utilizar con escenarios 3D, para poder incrustar en una pared del mapa un widget por poner un ejemplo.

De momento ya vá, el unico problema es que ahora quiero hacer widgets con scrollbar para poder hacer areas de texto y tengo un problema referente al clipping.

Como no quiero tener que cortar a mano todos los poligonos que se salgan de la región que hace scroll reduzco el viewport al area del objeto y así se hace automaticamente sin embargo al probarlo en 3D tengo el problema de que la región no es rectangular (ya que la camara es libre), ¿como puedo reducir el area de dibujo para que tenga la forma del widget? sabiendo las coordenadas 3D de cada esquina del widget.

Había pensado en hacerlo a traves de la matriz de proyection con los planos de clipping pero no se muy bien como... :S

Otra solución sería renderizar el contenido de la parte interior del area 'scrollable' en un buffer aparte, hacer copia en una textura y renderizar un quad, pero creo que eso sería muy costoso, además nunca he trabajado con más de un buffer en opengl y hasta donde se el stencil solo permite 8 bits de color.

Y el ultimo metodo sería ir elemento por elemento que esté dentro del area y cortarlo, lo cual no puedo hacer porque cada widget tiene una representación que es independiente de su contexto.

Que me sugeris?

Por un stratos menos tenso

tamat

 rayos, empiezo a creer que tengo dudas demasiado complejas para este foro  (nooo)  
Por un stratos menos tenso

Thenend

 
CitarOtra solución sería renderizar el contenido de la parte interior del area 'scrollable' en un buffer aparte, hacer copia en una textura y renderizar un quad, pero creo que eso sería muy costoso, además nunca he trabajado con más de un buffer en opengl y hasta donde se el stencil solo permite 8 bits de color.

Si lo que quieres decir es renderizar la parte visible de los datos "scrolleables" (toma palabro) a una textura y plantarla en un polígono, eso es lo que me parece mas razonable. No creo que pierdas mas velocidad que renderizando con el viewport reducido y haciendo lo que sea para ajustarlo. Hacer otra cosa me da la impresión que puede ser complicarse la vida innecesariamente.

Lo de los 8 bits de color del stencil me ha matao  :blink:  no lo entiendo. Si quieres hacer clipping claro que puedes usar el stencil para eliminar las partes que se salen del area donde quieres dibujar pero ¿que tiene que ver con el color? El stencil buffer, hasta donde yo se, no sirve para almacenar colores sino para hacer máscaras y conseguir efectos incrementando o decrementando el valor de stencil del pixel para que pase o no el test, igual es eso lo que no tienes claro. Perdona si soy yo el que no se entera.

tamat

 Nono, definitivamente el que no se entera soy yo, pensaba que el stencil era un buffer aparte para lo que quisieras pero limitado a 8 bits de color, pero por lo que he entendido tal vez sea lo que busco.

Lo de copiar a textuar para mi sería lo más sencillo pero imagina que el scroll ocupa la pantalla entera, estariamos hablando de una textura de 1024x768, miedo me da.

Por un stratos menos tenso

tamat

 Efectivamente, la respuesta que buscaba era 'crea una mascara de transparencia usando el stencil buffer', gracias The End, empezaba a pensar que nadie lo sabría.
Por un stratos menos tenso

Thenend

 De nada, me alegro de haber ayudado algo  :D  

tamat

 Refloto este thread de hace dos años porque me vuelvo a encontrar con la duda. En aquel momento creé la mascara mediante un poligono, dicho poligono definía la región de la pantalla donde se podría renderizar, pero ahora necesitaría algo más sofisticado.

Necesito alguna manera de definir una mascara desde una textura. Es decir, usar una imagen en escala de grises para definir qué zonas se pueden pintar y cuales no, pero me temo que para ello no tengo que usar el stencil buffer sino el alpha buffer.
Algun consejo de cómo hacerlo?

Gracias
Por un stratos menos tenso

senior wapo

 ¿ Y porqué no puedes con el stencil buffer ? A bote pronto se me ocurre que pintas el quad con la textura que hará de máscara en formato alpha8, escribiendo en el stencil, sin stencil test. Y luego pintas tus widgets con stencil test activado y sin modificar el stencil.

tamat

 No consigo pintar la textura en el stencil, solo me dibuja el poligono con un color constante. De todos modos tampoco creo que sea tan simple ya que mi textura es RGBA y el stencil es de 8 bits. Por otra parte creo que lo enfoco mal porque hasta donde yo se el stencil solo sirve para hacer mascaras binarias y yo necesito mascaras suaves, es decir, donde los diferentes tonos de gris simulen diferente cantidad de transparencia, así que creo que debería estar usando el buffer Alpha, pero no se muy bien como usarlo.

Alguien que me eche un cable? De momento lo hago todo en 2D para simplificar. Creo que los pases a seguir deberian ser los siguientes pero no estoy seguro:
- Pintar la escena sin alterar nunca el canal alpha
- Al llegar al objeto que tiene mascara pinto la mascara en el canal alpha (sin modificar los canales RGB)
- Activo un blending mode que use la alpha para mezclar los colores (src y dst)
- Pinto el objeto que debe quedar enmascarado
- Desactivo el modo de blending
- Limpio la capa alpha.
- Continuo renderizando la escena

Pero no se como forzar a que pinte una textura de 8 bits directamente en el canal apha.
Por un stratos menos tenso

senior wapo

 ¿ pero que tiene que ver que el stencil sea de 8 bits ? Es una máscara, con un stencil de 1 bit te vale (tienes operaciones mayor que, menor que , igual, etc...). Y si, es binaria, o acepta o rechaza. Stencil se usa para clipping no para componer colores.

Si no te entiendo mal, además de clipping buscas que tus poligonos usen texturas con alpha a la hora de dibujar los texels. Si quieres un mismo alpha para todo el poligono, usas GL_BLEND (blending general de la escena) y si buscas alphas diferentes por texel, para suavizar bordes, usas GL_RGB_COMBINE (combiners para los texels de los poligonos, puedes usar ambos a la vez) con dst 1-alpha y src alpha.

No veo donde está el problema, será que no entiendo lo que buscas, porque siempre puedes usar máscaras duras con stencil (sin alpha) y luego pintar encima el marco redondeado de la misma forma (dst 1-alpha,src alpha).

¿ Sobre la textura de solo alpha 8 bits has probado a desactivar que se escriba en el color buffer con glDisable ? Puedes seguir escribiendo en el zbuffer y en el stencil. Aclarame si no te he entendido lo que buscabas.

tamat

 Más o menos es lo que dices. Yo tengo dos texturas, una con una forma (por ejemplo una esfera difuminada) y la otra con una imagen, y quiero pintar la imagen usando la otra como máscara de transparencia. Mi mascara no es binaria ya que tiene diferentes valores en función de la cantidad de transparencia que desee para la imagen que voy a pintar.

Hasta ahora uso imagenes que llevan canal alpha y no hay ningun problema, uso Blend con SRC_ALPHA y demás para conseguir que quede como quiero, pero ahora me gustaría desvincular el canal alpha para que pueda elegir qué canal alpha tiene una imagen.

Pero los problemas son que no se como pintar sobre el canal alpha directamente. Había pensado lo que dices, de usar el glColorMask para bloquear los canales de color y dejar solo el alpha, pero entonces tengo una textura con 4 canales y solo uso el cuarto, no me aperece coherente. Puedo usar una textura de un unico canal para pintar sobre el canal alpha?

Lo de GL_RGB_COMBINE no lo he usado nunca, sirve para mezclar los tres canales antes de volcarlos al color buffer? entonces si que podría hacer lo que comentaba en el anterior parrafo. He buscado en google pero no me sale ninguna entrada, supongo que no es ese el nombre exacto.
Por un stratos menos tenso

marcode

 Dibuja primero la máscara como una imagen de colores o tonos grises (sin alpha para evitar complicaciones e incompatibilidades), y después el contenido con la operación de color glBlendFunc(GL_DST_COLOR, GL_ZERO), ¿no te sirve así?.
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]

senior wapo

 Bailé el orden de RGB y COMBINE.

Googlea GL_COMBINE_RGB y GL_COMBINE_ALPHA que se usan para multitexturas (en el fondo es lo que creo que quieres hacer).
Primero activas el modo combine para una etapa de textura con:
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
y luego asignas la operación y las fuentes (color/alpha de los vertices, texturas, etc..). Es muy largo para explicar en un post.


Una textura con formato GL_ALPHA y GL_UNSIGNED_BYTE (internal y external formats) es lo que buscas creo. Y si no, mira a ver con una de luminancia. Creo recordar que en el standard OpenGL está definido que el mismo valor se use para todos los canales (normalizado a 1.0 claro). (EDIT: internalformat=1, format=GL_ALPHA, type=GL_UNSIGNED_BYTE es lo que tengo en mi código).

PD: A lo mejor indagando en los fuentes de la libreria CEGUI puedes obtener pistas, es para hacer GUIs en motores 3D...

tamat

 Eso funcionaría si el fondo fuese negro, pero el fondo tiene otras imagenes, así que al pintar la mascara me pinta una imagen negra y blanca, luego al pintar la otra encima consigo que los pixeles que deberían ser semi transparentes se vean semioscuros. Así que no me sirve :/
Por un stratos menos tenso

Pogacha

 Editado.

Lo mejor es usar una textura para los guis ya seguro que no se actualizan constantemente y en definitiva es mas rapido que ir dibujandolos cada vez.
Para esto la solucion es usar multitextura, en openGL seria de lo mas facil, tienes que tener el alpha blending activado y la otra textura tiene que ser blanca con el alpha, ambas texturas se convinan por modulacion (lo que es por defecto) y luego usas el alpha blending que opera en el rasterizado. No hay secretos. Es la misma operacion que el lightmapping pero con alpha blending y una textura blanca con alpha, y si depaso quieres modular el color también te lo sacas gratis.

Encima si no quires usar multitexturas, primero dibujas la textura alpha desactivando la escritura en los canales de color, o sea que solo escriba el alpha y para la segunda textura usas alpha blending del modo glBlendFunc(GL_DEST_ALPHA, GL_ZERO) y listo! Esto requiere que el framebuffer tenga canal alpha.

Saludos.






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.