Forum

Quake-1 Shadows HELP!!!!

Discuss programming topics for the various GPL'd game engine sources.

Moderator: InsideQC Admins

Quake-1 Shadows HELP!!!!

Postby Stroggos » Tue Jun 23, 2009 2:27 am

There is a tutorial for quake 2 on how to add a z-buffer for the shadows in the old quakesrc stuff. How could you do the same for quake 1
Stroggos
 
Posts: 50
Joined: Tue Apr 14, 2009 11:40 am
Location: Australia

Postby revelator » Thu Jun 25, 2009 12:59 pm

Code: Select all
BOOL bSetupPixelFormat (HDC hDC)
{
    static PIXELFORMATDESCRIPTOR pfd =
   {
      sizeof(PIXELFORMATDESCRIPTOR),   // size of this pfd
      1,                        // version number
      PFD_DRAW_TO_WINDOW             // support window
      |  PFD_SUPPORT_OPENGL          // support OpenGL
      |  PFD_DOUBLEBUFFER ,         // double buffered
      PFD_TYPE_RGBA,               // RGBA type
      24,                        // 24-bit color depth (8 for each of r/g/b/a)
      0, 0, 0, 0, 0, 0,            // color bits ignored
      0,                        // 8 bits of your finest alpha if you please, my good man (set to none cos some implementations fall back to sw!!!)
      0,                        // shift bit ignored
      0,                        // no accumulation buffer
      0, 0, 0, 0,                // accum bits ignored
      24,                        // 24 bit z buffer.  because we have removed gl_ztrick, we can get away with this
      8,                        // 8 bit stencil buffer
      0,                        // no auxiliary buffer
      PFD_MAIN_PLANE,               // main layer
      0,                        // reserved
      0, 0, 0                     // layer masks ignored
    };

    int pixelformat;

    if ((pixelformat = ChoosePixelFormat (hDC, &pfd)) == 0)
    {
        MessageBox (NULL, "ChoosePixelFormat failed", "Error", MB_OK);
        return FALSE;
    }

    if (SetPixelFormat (hDC, pixelformat, &pfd) == FALSE)
    {
        MessageBox (NULL, "SetPixelFormat failed", "Error", MB_OK);
        return FALSE;
    }

   // the stencil buffer should be available on everything aside from 3dfx so this is really a redundant
   // test, cos Realm will work on everything aside from a 3dfx...  besides, if you have a 3dfx, not
   // having a stencil buffer will be least of your problems...
   if (!pfd.cStencilBits) Sys_Error ("No Stencil Buffer!!!");

    return TRUE;
}


above might give a hint :) look in gl_vidnt.c

for the stencil shadows i have some code floating around somewhere on my harddrive. ill post it when i found it ;)
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Postby revelator » Thu Jun 25, 2009 1:15 pm

ah here we go.

somewhere at the top of gl_vidnt.c add

qboolean stencildraw = false;

now modify the previous code


Code: Select all
BOOL bSetupPixelFormat (HDC hDC)
{
    static PIXELFORMATDESCRIPTOR pfd =
   {
      sizeof(PIXELFORMATDESCRIPTOR),   // size of this pfd
      1,                        // version number
      PFD_DRAW_TO_WINDOW             // support window
      |  PFD_SUPPORT_OPENGL          // support OpenGL
      |  PFD_DOUBLEBUFFER ,         // double buffered
      PFD_TYPE_RGBA,               // RGBA type
      24,                        // 24-bit color depth (8 for each of r/g/b/a)
      0, 0, 0, 0, 0, 0,            // color bits ignored
      0,                        // 8 bits of your finest alpha if you please, my good man (set to none cos some implementations fall back to sw!!!)
      0,                        // shift bit ignored
      0,                        // no accumulation buffer
      0, 0, 0, 0,                // accum bits ignored
      24,                        // 24 bit z buffer.  because we have removed gl_ztrick, we can get away with this
      8,                        // 8 bit stencil buffer
      0,                        // no auxiliary buffer
      PFD_MAIN_PLANE,               // main layer
      0,                        // reserved
      0, 0, 0                     // layer masks ignored
    };

    int pixelformat;

    if ((pixelformat = ChoosePixelFormat (hDC, &pfd)) == 0)
    {
        MessageBox (NULL, "ChoosePixelFormat failed", "Error", MB_OK);
        return FALSE;
    }

    if (SetPixelFormat (hDC, pixelformat, &pfd) == FALSE)
    {
        MessageBox (NULL, "SetPixelFormat failed", "Error", MB_OK);
        return FALSE;
    }

   // the stencil buffer should be available on everything aside from 3dfx so this is really a redundant
   // test, cos Realm will work on everything aside from a 3dfx...  besides, if you have a 3dfx, not
   // having a stencil buffer will be least of your problems... 
 if (pfd.cStencilBits)
      stencildraw = true;  // we got a stencil buffer

    return TRUE;
}


in vid.h

extern qboolean stencildraw;

in gl_rmain.c

Code: Select all
void GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum)
{
   trivertx_t   *verts;
   trace_t     downtrace;
   int         *order, count;
   vec3_t      point;
   vec3_t      downmove;
   float       s1, c1;
   float      height, lheight;

   lheight = currententity->origin[2] - lightspot[2];
   height = 1 - lheight;

   verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata);
   verts += posenum * paliashdr->poseverts;
   order = (int *)((byte *)paliashdr + paliashdr->commands);

   VectorCopy (currententity->origin, downmove);
   downmove[2] = downmove[2] - 4096;
   memset (&downtrace, 0, sizeof(downtrace));

   SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, currententity->origin, downmove, &downtrace);

   s1 = sin( currententity->angles[1] / 180*M_PI);
   c1 = cos( currententity->angles[1] / 180*M_PI);

   if (stencildraw) {
      glEnable(GL_STENCIL_TEST);
      glStencilFunc(GL_EQUAL, 1, 2);
      glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
   }

   while ((count = *order++)) {
      // get the vertex count and primitive type
      if (count < 0) {
         count = -count;
         glBegin (GL_TRIANGLE_FAN);
      } else {
         glBegin (GL_TRIANGLE_STRIP);
      } do {
         // texture coordinates come from the draw list
         // (skipped for shadows) glTexCoord2fv ((float *)order);
         order += 2;

         // normals and vertexes come from the frame list
         point[0] = verts->v[0] * paliashdr->scale[0] + paliashdr->scale_origin[0];
         point[1] = verts->v[1] * paliashdr->scale[1] + paliashdr->scale_origin[1];
         point[2] = verts->v[2] * paliashdr->scale[2] + paliashdr->scale_origin[2];

         point[0] -= shadevector[0]*(point[0]);
         point[1] -= shadevector[1]*(point[1]);
         point[2] -= shadevector[2]*(point[2]);

         point[2] = point[2] - (currententity->origin[2] - downtrace.endpos[2]);

         point[2] += ((point[1] * (s1 * downtrace.plane.normal[0])) -
                   (point[0] * (c1 * downtrace.plane.normal[0])) -
                   (point[0] * (s1 * downtrace.plane.normal[1])) -
                   (point[1] * (c1 * downtrace.plane.normal[1]))) + 
                  ((1.0 - downtrace.plane.normal[2])*20) + 0.2;

         glVertex3fv (point);

         verts++;
      } while (--count);

      glEnd ();
   }   

   if (stencildraw) {
      glDisable(GL_STENCIL_TEST);
   }
}


and if you use lerped shadows

Code: Select all
void GL_DrawAliasBlendedShadow (aliashdr_t *paliashdr, int pose1, int pose2, entity_t *e)
{
   trivertx_t   *verts1, *verts2;
   trace_t     downtrace;
   int         *order, count;
   vec3_t      point1, point2, d;
   vec3_t      downmove;
   float        s1, c1;
   float      height, lheight, blend;

   blend = min(1, (cl.time - e->frame_start_time) / e->frame_interval);

   if (cl.paused || blend > 1) blend = 1;

   lheight = e->origin[2] - lightspot[2];
   height  = 1 - lheight;

   verts1 = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata);
   verts2 = verts1;

   verts1 += pose1 * paliashdr->poseverts;
   verts2 += pose2 * paliashdr->poseverts;

   order = (int *)((byte *)paliashdr + paliashdr->commands);

   VectorCopy (currententity->origin, downmove);
   downmove[2] = downmove[2] - 4096;
   memset (&downtrace, 0, sizeof(downtrace));

   SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, currententity->origin, downmove, &downtrace);

   // calculate the all important angles
   s1 = sin( currententity->angles[1]/180*M_PI);
   c1 = cos( currententity->angles[1]/180*M_PI);

   if (stencildraw) {
      glEnable(GL_STENCIL_TEST);
      glStencilFunc(GL_EQUAL, 1, 2);
      glStencilOp(GL_KEEP,GL_KEEP,GL_INCR);
   }

   while ((count = *order++)) {
      // get the vertex count and primitive type
      if (count < 0) {
         count = -count;
         glBegin (GL_TRIANGLE_FAN);
      } else {
         glBegin (GL_TRIANGLE_STRIP);
      } do {
         order += 2;

         point1[0] = verts1->v[0] * paliashdr->scale[0] + paliashdr->scale_origin[0];
         point1[1] = verts1->v[1] * paliashdr->scale[1] + paliashdr->scale_origin[1];
         point1[2] = verts1->v[2] * paliashdr->scale[2] + paliashdr->scale_origin[2];

         point1[0] -= shadevector[0]*(point1[2]+lheight);
         point1[1] -= shadevector[1]*(point1[2]+lheight);

         point2[0] = verts2->v[0] * paliashdr->scale[0] + paliashdr->scale_origin[0];
         point2[1] = verts2->v[1] * paliashdr->scale[1] + paliashdr->scale_origin[1];
         point2[2] = verts2->v[2] * paliashdr->scale[2] + paliashdr->scale_origin[2];

         point2[0] -= shadevector[0]*(point2[2]+lheight);
         point2[1] -= shadevector[1]*(point2[2]+lheight);

         VectorSubtract (point2, point1, d);

         point1[0] = point1[0] + (blend * d[0]);
         point1[1] = point1[1] + (blend * d[1]);
         point1[2] = point1[2] + (blend * d[2]);

         point1[2] =  - (currententity->origin[2] - downtrace.endpos[2]) ;

         point1[2] += ((point1[1] * (s1 * downtrace.plane.normal[0])) -
                    (point1[0] * (c1 * downtrace.plane.normal[0])) -
                    (point1[0] * (s1 * downtrace.plane.normal[1])) -
                    (point1[1] * (c1 * downtrace.plane.normal[1]))) +
                   ((1.0 - downtrace.plane.normal[2])*20) + 0.2 ;

         glVertex3fv (point1);

         verts1++;
         verts2++;
      } while (--count);

      glEnd ();
   }

   if (stencildraw) {
      glDisable(GL_STENCIL_TEST);
   }
}


and in this

Code: Select all
void R_Clear (void)
{
   static qboolean   cleartogray;
   qboolean      clear = false;

   if (gl_clear.value) {
      clear = true;
      if (cleartogray) {
         glClearColor (1, 0, 0, 0);
         cleartogray = false;
      }
   } else if (!vid_hwgamma_enabled && gl_contrast.value > 1) {
      clear = true;
      if (!cleartogray) {
         glClearColor (0.1, 0.1, 0.1, 0);
         cleartogray = true;
      }
   }

   if (gl_ztrick.value) {
      if (clear) {
         glClear (GL_COLOR_BUFFER_BIT);
      }
      gl_ztrickframe = !gl_ztrickframe;
      if (gl_ztrickframe) {
         gldepthmin = 0;
         gldepthmax = 0.49999;
         glDepthFunc (GL_LEQUAL);
      } else {
         gldepthmin = 1;
         gldepthmax = 0.5;
         glDepthFunc (GL_GEQUAL);
      }
   } else {
      if (clear) {
         glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      } else {
         glClear (GL_DEPTH_BUFFER_BIT);
      }
      gldepthmin = 0;
      gldepthmax = 1;
      glDepthFunc (GL_LEQUAL);
   }

   if (stencildraw  && r_shadows.value > 0) {
      glClearStencil(TRUE);
      glClear(GL_STENCIL_BUFFER_BIT);
   }
   glDepthRange (gldepthmin, gldepthmax);
}


your code might differ a bit, but its pretty stright forward :)
this is from a modified joequake i worked on. tei and others later added some more modifications so the shadow intensity varied depending on how far from the floor the player/monsters etc where.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Postby Stroggos » Fri Jun 26, 2009 6:07 am

Thanks o apreciate it!!!
Stroggos
 
Posts: 50
Joined: Tue Apr 14, 2009 11:40 am
Location: Australia

Postby revelator » Fri Jun 26, 2009 8:33 am

;) my pleasure.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger


Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 1 guest