Foros - Stratos

Programadores => Programación gráfica => Mensaje iniciado por: The-Force en 11 de Junio de 2007, 08:45:35 PM

Título: Problema: Stencil Buffer, Shadown Volumes con C# y CSOpenGL
Publicado por: The-Force en 11 de Junio de 2007, 08:45:35 PM
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
Título: Problema: Stencil Buffer, Shadown Volumes con C# y CSOpenGL
Publicado por: Sante en 11 de Junio de 2007, 10:58:58 PM
Te has asegurado de que al poner el pixel format le estas metiendo los bits del stencil para que lo active?
Título: Problema: Stencil Buffer, Shadown Volumes con C# y CSOpenGL
Publicado por: Vicente en 11 de Junio de 2007, 11:49:12 PM
CSGL no estaba muerto? Yo miraría TAO (que si que está bien vivo ;)).

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

Vicente
Título: Problema: Stencil Buffer, Shadown Volumes con C# y CSOpenGL
Publicado por: The-Force en 12 de Junio de 2007, 03:40:23 AM
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
Título: Problema: Stencil Buffer, Shadown Volumes con C# y CSOpenGL
Publicado por: Vicente en 12 de Junio de 2007, 08:11:37 AM
Thks por la info, le daré un vistazo a ver que veo :) Un saludo!

Vicente
Título: Problema: Stencil Buffer, Shadown Volumes con C# y CSOpenGL
Publicado por: Sante en 12 de Junio de 2007, 05:35:21 PM
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
};
Título: Problema: Stencil Buffer, Shadown Volumes con C# y CSOpenGL
Publicado por: The-Force en 13 de Junio de 2007, 02:58:55 AM
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
Título: Problema: Stencil Buffer, Shadown Volumes con C# y CSOpenGL
Publicado por: The-Force en 16 de Junio de 2007, 04:37:06 AM
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
Título: Problema: Stencil Buffer, Shadown Volumes con C# y CSOpenGL
Publicado por: BeRSeRKeR en 16 de Junio de 2007, 12:50:32 PM
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 (http://ati.amd.com/developer/SwedenTechDay/03_Clever_Shader_Tricks.pdf), el apartado de Skyboxes.

Saludos.
Título: Problema: Stencil Buffer, Shadown Volumes con C# y CSOpenGL
Publicado por: marcode en 16 de Junio de 2007, 04:55:59 PM
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
Título: Problema: Stencil Buffer, Shadown Volumes con C# y CSOpenGL
Publicado por: The-Force en 17 de Junio de 2007, 07:48:40 PM
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#.