Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Cambiar El Color De Un Vértice Sin Lockear El Vf

Iniciado por Loover, 11 de Diciembre de 2003, 02:03:42 AM

« anterior - próximo »

Loover

 Buenas.

Estoy portando una serie de clases que había implementado con OpenGL a Direct3d y me han surgido algunas dudas.
Una de ellas es la forma en que yo hacía una especie de "entintado" en las imágenes:

OPENGL
A cada frame:

glColor4f (1.0f, 1.0f, 1.0f, 0.5f);
glCallList (displayList);

Y ale, la imagen que estaba en displayList se entintaba.

DIRECT3D

¿Cómo hago eso a cada frame en Direct3d sin tener que lockear el vertex buffer, cambiar el color de todos los vértices, unlockear y dibujar?

Porque según tengo entendido, lockear a cada frame es muy costoso.

Un saludo!
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

BeRSeRKeR

 Lo único que se me ocurre ahora mismo es, o bien utilizar un material o bien utilizar vertex shaders. Esta última me parece la mejor opción.

Ten en cuenta que con un vertex shader puedes modificar todas las propiedades de los vértices sin bloquear el vertex buffer para nada.

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

Loover

 Sí, eso es lo que había pensado tras ver el código de la semana de Ak47 (que por cierto, se lo curró). Pero me parecía extranísimo que una cosa que es tan sencilla de hacer en OpenGl (sin pérdida de velocidad) sea bastante más complicada en DX9 (tirar de shaders).
No sé, me parece muy fuerte.

Sino hay más remedio...

Gracias

PD: ¿Cómo se haría con el material? ¿Sería muy costoso? Si necesito activar la iluminación sí...
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

MChiz

 Hola:

Si que se puede hacer lo que quieres sin necesidad de hacer algo tan complejo. Has de usar el TextureFactor.
Si quieres tener un color por vertice, textura y ademas todo esto poder tintarlo de un color, debes hacer:

En el stage 0 pones que se multiplique la textura y el color por vertice.
En el stage 1 pones que el resultado anterior se multiplique por el TextureFactor.
El codigo seria algo asi:
p_Device9->SetRenderState( D3DRS_TEXTUREFACTOR, color/* Aqui pon el color que quieras*/ );
p_Device9->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
p_Device9->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
p_Device9->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
p_Device9->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE );
p_Device9->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_CURRENT );
p_Device9->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_TFACTOR );

Si solamente quieres texture y tintar de un color:

En el stage 0 pones que se multiplique la textura y el TextureFactor:
Y su codigo correspondiente:
p_Device9->SetRenderState( D3DRS_TEXTUREFACTOR, color/* Aqui pon el color que quieras*/ );
p_Device9->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
p_Device9->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
p_Device9->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_TFACTOR );

Espero que te sirva!

Un saludote!!

Loover

 Ey! Muchas gracias, aún no lo he probado pero tiene buena pinta.
Un par de dudas:
- ¿El color se lo meto con esto? color = D3DCOLOR_COLORVALUE (r, g, b, a); ¿Si en a pongo un valor 128 se verá semitransparente siempre que esté activado el alphablending?
- ¿Esto es usando multitextura, no? Vaya, no la necesitaba en OGL. ¿Cómo se hace para saber si una tarjeta soporta multitextura?

Gracias
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

BeRSeRKeR

 En realidad, creo que MChiz ha tenido un pequeño despiste (supongo que al copiar y pegar).

Si sólo quieres aplicar una textura y tintar la superficie, sólo necesitas una unidad de textura. El código sería:

p_Device9->SetRenderState( D3DRS_TEXTUREFACTOR, color/* Aqui pon el color que quieras*/ );
p_Device9->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
p_Device9->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
p_Device9->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR );

De todas formas, ¿qué aceleradora no soporta al menos dos unidades de textura?. Que yo sepa la voodoo1 ya soportaba dos unidades.

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

Loover

 ¿Y en el caso en el que tb usa el diffuse tb se puede hacer todo en el stage 0?
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Zaelsius

 No, sólo se pueden utilizar dos argumentos por textura. (textura+factor, o textura+vertexcolor, etc)

BeRSeRKeR

 En ese caso creo que el código que necesitas es justamente el primer caso que te ha puesto MChiz. Ahí sí estarías utilizando multitextura. La otra opción para no utilizar multitextura ya sabes que es bloquear el vertex buffer y la otra, y la mejor opción, utilizar vertex shaders.

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

BeRSeRKeR

 Juas, esto:

CitarPor cierto, después de probar los vertex & pixel shaders, la fixed pipeline acaba pareciéndote patética

lo quería decir en este mensaje no en el otro que ha puesto MChiz. Aunque bueno, nunca está de más decirlo :D

¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

MChiz

 Buens!

Lo primerisimo de todo: Berserker tiene razon; me equivoque al copypastear :b Lo que ha puesto Berserker esta bien.

Una cosa que parece estar confundida: El usar 2 stages no significa utilizar multitextura ( CREO ). Lo digo porque he llegado a hacer muchas operaciones, sobrepasando el limite de texturas simultaneas de mi tarjeta, y todo rula. Asi que CREO que utilizar el primer metodo que expuse no te obliga a tener multitextura. Que alguien me corrija si me equivoco ( o pruebalo tu mismo : ) )

Y a lo otro que decias, Loover: Si, si le metes 128 de alpha y tienes el alpha blending activado, funcionara : )

Saludotes!!!!!

Zaelsius

 ¿Podría ser que Direct3D hace automáticamente las siguientes pasadas si no se puede pintar todo en una pasada? :huh:  

MChiz

 Me pareceria demasiado raro ( y bonito ;b ).  Pensemoslo como si fuese un pixel shader:

float4 main( InData in, uniform sampler2D tex1, uniform sampler2D tex2 ) {
   return ( float4 )tex2D( tex1, in.texCoord0 ) + ( float4 )tex2D( tex2, in.texCoord0 );
}

Este anterior shader NECESITA dos unidades de textura.

float4 main( InData in, uniform sampler2D tex1, uniform float4 textureFactor ) {
   return ( float4 )tex2D( tex1, in.texCoord0 ) + textureFactor;
}

Y este utiliza UNA unidad de textura y ADEMAS tiene una constante que, en este caso, es el textureFactor.
Se me acaba de ocurrir... pienso que si va por este camino, esta claro que una stage NO equivale a una unidad de textura.

Saludoteeees!

_Grey

 
glColor4f (1.0f, 1.0f, 1.0f, 0.5f);
glCallList (displayList);


Usa Material, y prepara el SetRenderSatge, para que te lo tenga encuenta, en lugar del color independiente de cada vertice.

PD: Por que sacais el tema de las texturas!? :blink:  :ph34r:  

MChiz

 Sigo pensando que es mas facil con el TextureFactor...






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.