Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Problema: Stencil Buffer, Shadown Volumes con C# y CSOpenGL

Iniciado por The-Force, 11 de Junio de 2007, 08:45:35 PM

« anterior - próximo »

The-Force

Estoy tratando de implementar sombras con shadown volumes basandome en la leccion 27 de los tutoriales de NEHE y tengo algun problema relacionado con el stencil buffer.

Los shadown volumes son generados correctamente. Para asegurarme los he  dibujado en el color buffer y estan bien. El problema es ... o estoy haciendo algo mal con el stencil buffer o este no esta funcionando para nada (que es la sensacion que da).

Es la primera vez que uso el stencil buffer asi que no se muy bien que estoy haciendo con este codigo.

Pongo parte del codigo a continuacion (la parte que importa supongo):

Funcion que dibuja las sombras y que se llama despues de dibujar la escena.

       private void LanzarSombras()
       {
           GL.glPushAttrib(GL.GL_COLOR_BUFFER_BIT |
                           GL.GL_DEPTH_BUFFER_BIT |
                           GL.GL_ENABLE_BIT |
                           GL.GL_POLYGON_BIT |
                           GL.GL_STENCIL_BUFFER_BIT);
           GL.glDisable(GL.GL_LIGHTING);
           GL.glDepthMask(0);                    
           GL.glDepthFunc(GL.GL_LEQUAL);
           GL.glEnable(GL.GL_STENCIL_TEST);  
           GL.glColorMask(0, 0, 0, 0);                                    
           GL.glStencilFunc(GL.GL_ALWAYS, 1, 0xffffffff);

           foreach(CObjeto Objeto in Escena.Objetos)
           {
               if(Objeto.Tipo == 1)
               {
                   CObjeto3D O3D = (CObjeto3D)Objeto;
                   if (O3D.ProduceSombra)
                   {
                       foreach (CLuz Luz in Escena.Luces)
                       {
                           if (Luz.ProduceSombra)
                           {
                               CShadownVolume.MarcarCarasIluminadas(O3D, Luz.Sistema.Origen());
                               GL.glPushMatrix();
                               GL.glMultMatrixf(O3D.Sistema.ToFloatv());

                               // First Pass. Increase Stencil Value In The Shadow
                               GL.glFrontFace(GL.GL_CCW);
                               GL.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_INCR);
                               DibujarSombra(O3D, Luz.Sistema.Origen());
                               // Second Pass. Decrease Stencil Value In The Shadow
                               GL.glFrontFace(GL.GL_CW);
                               GL.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_DECR);
                               DibujarSombra(O3D, Luz.Sistema.Origen());
                               GL.glPopMatrix();
                           }
                       }
                   }
               }
           }

           GL.glFrontFace(GL.GL_CCW);
           GL.glColorMask(1, 1, 1, 1);
           GL.glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
           GL.glEnable(GL.GL_BLEND);
           GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
           GL.glStencilFunc(GL.GL_NOTEQUAL, 0, 0xFFFFFFFF);
           GL.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP);
           GL.glPushMatrix();
           GL.glLoadIdentity();
           GL.glBegin(GL.GL_TRIANGLE_STRIP);
               GL.glVertex3f(-10f, 10f, -0.10f);
               GL.glVertex3f(-10f, -10f, -0.10f);
               GL.glVertex3f(10f, 10f, -0.10f);
               GL.glVertex3f(10f, -10f, -0.10f);
           GL.glEnd();
           GL.glPopMatrix();
           GL.glPopAttrib();

       }


Agradeceria cualquier ayuda que me podais prestar para intentar sacar esto adelante  ^^.

Saludos

Sante

Te has asegurado de que al poner el pixel format le estas metiendo los bits del stencil para que lo active?

Vicente

CSGL no estaba muerto? Yo miraría TAO (que si que está bien vivo ;)).

Respecto a lo del stencil ni idea :( Un saludo!

Vicente

The-Force

Cita de: "Sante"
Te has asegurado de que al poner el pixel format le estas metiendo los bits del stencil para que lo active?

No tengo nidea de como cambiar el pixel fomat :(

Cita de: "Vicente"
CSGL no estaba muerto? Yo miraría TAO (que si que está bien vivo ;)).

CSOpenGL y CSGL creo que no son el mismo wrapper (como se diga). Uso el CSOpenGL por que es con el que hemos estado haciendo las practicas en la uni. Empezare a mirarme TAO

Vicente

Thks por la info, le daré un vistazo a ver que veo :) Un saludo!

Vicente

Sante

Cita de: "The-Force"No tengo nidea de como cambiar el pixel fomat :(

Hombre, no se como sera en C#, pero al menos con C/C++ tienes que darle un descriptor del pixel format donde le indicas cuantos bits tiene que tener de profundidad de color, cuantos bits para el Z-buffer, y tambien si quieres stencil, le tienes que pasar los bits que quieres que tenga.

Sacado de Nehe:


static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
1, // Use Stencil Buffer ( * Important * )
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};

The-Force

Bueno despues de investigar un poco me voy a quedar con el port de ventana+opengl de NEHE para TAO, donde se ve claramente como modificar el pixel format, y partire desde ahi añadiendo lo que habia hecho con CSOpenGL.

Muchas gracias por la ayuda. Si consigo que me funcionen las sombras ya pondre algo por aqui ^^

Saludos

The-Force

Bueno por fin me funcionan los shadow volumes portando mi codigo a Tao.
2 cosillas mas:

Cuando activo las sombras el framerate baja burtalmente. Que deberia hacer para solucionar esto? shaders?

Para explicaros el otro problema os cuento que lo que estoy haciendo es un  minijuego espacial (que tipico si xD). Para pintar el fondo de estrellas dibujo una esfera con una textura (tipico tambien) y con el test de profundidad desactivado, de esta manera todo lo que dibuje despues se dibujara sobre de esto. A continuacion se dibujan el resto de objetos de la escena. El problema viene con el shadow volume de los objetos en la escena ya que me proyectan sombras sombre este fondo y no deberia ya que al tener desactivado el test de profundidad al pintar el fondo, el stencil buffer no deberia fallar ahi puesto que no deberia haber informacion de profundidad para esos pixels. ... o me estoy equivocando ?

saludos

BeRSeRKeR

Cita de: "The-Force"Cuando activo las sombras el framerate baja burtalmente. Que deberia hacer para solucionar esto? shaders?
Que el frame rate descienda es normal cuando se hace uso del stencil buffer. Debes tener en cuenta varios factores como la densidad de la malla de los modelos que proyectan sombras.

Cita de: "The-Force"Para pintar el fondo de estrellas dibujo una esfera con una textura (tipico tambien) y con el test de profundidad desactivado, de esta manera todo lo que dibuje despues se dibujara sobre de esto. A continuacion se dibujan el resto de objetos de la escena. El problema viene con el shadow volume de los objetos en la escena ya que me proyectan sombras sombre este fondo y no deberia ya que al tener desactivado el test de profundidad al pintar el fondo, el stencil buffer no deberia fallar ahi puesto que no deberia haber informacion de profundidad para esos pixels. ... o me estoy equivocando ?
No basta con desactivar el test de profundidad, también tienes que desactivar la escritura en el depth buffer. Por otra parte, siempre se recomienda pintar el skybox al final, tras los objetos opacos. Echale un vistazo a esta presentación, el apartado de Skyboxes.

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

marcode

Para acelerar el asunto de las sombras puedes dibujar simultáneamente las caras delanteras y traseras del volumen, desactivando el CULL FACE.

Para ello hay que usar unas extensiones que sirven para indicar que haga la operación de stencil correspondiente (incrementar o decrementar) para los polígonos traseros y delanteros de manera independiente.

Abajo de esta página hay un código muy completo, que sirve para las ATI y para las Nvidia y para las tarjetas que no soportan el "single pass". Incluso tiene posibilidad de usar el z-fail.

http://www.gamedev.net/community/forums/topic.asp?topic_id=265278&whichpage=1&#1625370
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]

The-Force

con GL.glDepthMask(0) no se desactiva la escritura en el buffer Z ??

Otra cosa. El stencil se nota en los fps pero lo que mas se nota es el dibujo manual de la geometria de la sombra. Me pasa que en c# dibujar cualquie geometria cara a cara sin usar display lists va tremendamente lento y no se porque. En otro minijuego similar ke hice hace tiempo con c++ esto no pasaba de hecho no sabia ni usar display list en aquella epoca.
Como es posible que sin usar display list en c++ me fuera mas de 20 (por decir algo) veces mas rapido que en c#.






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.